assembly - 如何识别汇编代码中的调用约定

标签 assembly nasm calling-convention

我有三个汇编代码片段,我应该为每个片段确定正确的调用约定(CDECL、STDCALL、FASTCALL)。为了识别调用约定,我正在寻找堆栈清理器,它是调用者或被调用者。但是,如果我找不到我认为看起来像“add esp,8”的清理代码怎么办?我的方法有错吗?我必须搜索其他调用约定特征吗?下面是代码片段。

片段1

push ebp
mov ebp , esp
sub esp , 0x8
mov [ ebp-0x4 ] , eax
mov [ ebp-0x8 ] , edx
mov eax , [ ebp-0x8 ]
mov edx , [ ebp-0x4 ]
add edx , eax
mov eax , ecx
add eax , edx
leave
ret

片段2

push ebp
mov ebp , esp
mov eax , [ ebp+0xC]
mov edx , [ ebp+0x8 ]
add edx , eax
mov eax , [ ebp+0x10 ]
add eax , edx
pop ebp
ret 0xC

片段3

push ebp
mov ebp , esp
mov eax , [ ebp+0xC]
mov edx , [ ebp+0x8 ]
add edx , eax
mov eax , [ ebp+0x10 ]
add eax , edx
pop ebp
ret

最佳答案

第一个 Fragment 是 fastcall 调用约定 因为该过程使用了寄存器(EAX,EDX)而没有为其赋值 - 这意味着调用者使用寄存器来传递参数 - 就像行中

mov [ ebp-0x4 ] , eax

第二个片段是 stdcall 调用约定,因为该过程清除了堆栈中的参数

ret 0xC

第三个片段是 cdecl 调用约定,因为该过程从堆栈中获取参数,但没有清除堆栈中的参数

ret

每一项的快速分数将为:

fastcall:调用者使用寄存器来传递前两个参数。

stdcall:被调用者必须清理堆栈。

cdecl:调用者必须清理堆栈。

更多信息请参阅维基百科

http://en.wikipedia.org/wiki/X86_calling_conventions

关于assembly - 如何识别汇编代码中的调用约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30061646/

相关文章:

c++ - 内联函数和 __thiscall __cdecl Bjarne String 示例

assembly - 在汇编级编程中用 db 定义一个字节后增加一个值

assembly - 有没有办法在 32 位寄存器指令中保留字大小的立即数

linux - x86 ASM Linux - 使用 .bss 部分

c - 参数比预期更多的函数调用

c - 在调用传递多个参数的函数时处理进入堆栈的被调用者寄存器

assembly - shl 指令抛出 'error A2070 : invalid instruction operands'

gcc - c语言中两个字符串之间的冒号是什么?

assembly - 一个操作码字节如何根据 "register/opcode"字段解码为不同的指令?那是什么?

c - 如何在x86实模式ISR中将数据存储到全局变量中?