如何在被调用方中获取参数整数?

how to get argument integer in callee?

我有以下代码 (caller.c):

#include <stdio.h>

extern int callee(int);

int main(int argc, char *argv[]){
  callee(4);
  return 1;
}

和(callee.s):

.globl callee

callee:
  pop %eax
  add , %eax
  ret

我编译: gcc -m32 caller.c callee.s

和运行:

./a.out

分段错误(核心已转储)

我想知道我的错误是什么 is/are 因为我认为 main 现在应该压栈的 32 位数字。我没有更改堆栈,因此被调用者现在应该能够从同一个堆栈中弹出该数字。也许我应该在弹出之前添加 (add $4, %esp) (如果被调用者的地址在 "way"/actually been popped 中)。我也尝试过但没有成功。被调用者现在应该从堆栈中获取数字并将其加 4。 eax-register 应该是从被调用者到调用者的 return 值应该被保留的地方(调用约定),但这里我忽略了 return 值。

有人可以帮助我吗?

相关问题: calling assembly function from c

调用约定: https://en.wikipedia.org/wiki/X86_calling_conventions

(使用 x86-32 调用约定,)函数的参数首先被压入堆栈 ,然后是 return 地址。因此,您的 pop 指令弹出了 return 地址 ,随后的 ret 试图 return 到未映射的地址 0x00000004内存,导致崩溃。

另外,在这个约定中,被调用者应该弹出它的参数。来电者会这样做。

你应该写的代码是

callee:
    movl 4(%esp), %eax
    addl , %eax
    ret

你可以自己编译确认一下

unsigned int callee(unsigned int x) { return x + 4; }

使用选项 -m32 -O2 -S -fomit-frame-pointer 并检查生成的 .s 文件;你应该得到与上面相同的汇编代码。