我正在尝试链接x86汇编和C。
我的C程序:
extern int plus_10(int);
# include <stdio.h>
int main() {
int x = plus_10(40);
printf("%d\n", x);
return 0;
}
我的汇编程序:
[bits 32]
section .text
global plus_10
plus_10:
pop edx
mov eax, 10
add eax, edx
ret
我编译和链接这两个如下:
gcc -c prog.c -o prog_c.o -m32
nasm -f elf32 prog.asm -o prog_asm.o
gcc prog_c.o prog_asm.o -m32
然而,当我运行结果文件时,我得到了一个分段错误。
但是当我把
弹出EDX
与
移动EDX,[特别是+4]
程序运行正常。2有没有人能解释一下为什么会发生这种情况?
1条答案
按热度按时间ig9co6j11#
这可能是
int x = plus_10(40);
的汇编代码现在,当你调用
plus_10
时,call
指令将地址retadd
压入堆栈,它实际上是push
+jmp
,ret
实际上是pop eip
。在
plus_10
函数中,堆栈如下所示:ESP
指向包含返回地址的内存位置。现在如果你使用
pop edx
,返回地址会变成edx
,堆栈看起来像这样:现在,如果您在此时执行
ret
,程序实际上将跳转到地址40,并且很可能出现segfault或以其他一些不可预测的方式运行。编译器生成的实际汇编代码可能不同,但这说明了问题所在。
顺便说一句,编写函数的一种更有效的方法是:对于这个小函数的非内联版本,大多数编译器都会这样做。
这比