如何知道第一个函数参数在哪里?

时间:2014-01-17 16:32:22

标签: function assembly x86 arguments cpu-registers

我只是想知道,如果我有这个ASM功能:

PUSH EBP
MOV EBP, ESP
SUB ESP, 8
LEAVE
RETN 8

它什么都不做,需要两个4字节的参数。似乎第一个参数位于EBP+8,第二个参数位于EBP+12。但是,怎么知道呢?因为如果函数需要三个4字节参数,那么第三个参数将在EBP+16。第一个参数是否总是在EBP+8,然后我只需要添加参数大小以获得下一个参数?如果是,为什么8?

提前致谢。

3 个答案:

答案 0 :(得分:3)

它是8,因为通常,EBP + 0 =调用者保存的EBP,EBP + 4 =返回地址,EBP + 8 =第一个基于堆栈的参数。

此外,这样的偏移量通常以十六进制值表示,因此第二个基于堆栈的参数将为EBP + C,第三个将为EBP + 10.

推导函数的调用约定的一个好方法(不是100%)是看函数的调用者如何在调用函数之前准备寄存器和/或堆栈(也就是在函数返回之后)

答案 1 :(得分:2)

使用堆栈帧时,第一个堆栈参数将始终位于[EBP+8],但调用约定可以在两个寄存器(通用和SIMD)和堆栈中传递参数。

您的示例假设您使用标准化约定,例如__stdcall__cdecl,但__fastcall和VC ++ 13的新__vectorcall中的参数将是通用的, SIMD寄存器(寄存器本身根据ABI Sys-V与MS的不同而不同)。

答案 2 :(得分:1)

函数参数的布局取决于用于此函数的调用约定。调用约定可以是函数创建者想象的任何东西。