ASM转C:4(%esp)指的是什么

Edo*_*zen 1 c assembly

我正在尝试将以下汇编代码转换为 C 代码:

fct:
    movl 4(%esp), %eax
    cmpl $0,%eax
    jg n
    movl $-1,%eax
    ret
n:  movl $0,%ebx
    movl %eax, %ecx
    movl $0, %eax
    movl $0, %edx
l:  addl $2, %ebx
    addl %ebx, %eax
    addl $1, %edx
    cmpl %ecx, %edx
    jl l
    ret
Run Code Online (Sandbox Code Playgroud)

因为我认为我可以很容易地翻译其中的大部分内容,所以我似乎找不到第一行(movl 4(%esp), %eax)的作用。4(%esp) 在这种情况下指什么?我知道 %esp 寄存器指的是堆中的最后一条指令,而 4(%esp) 指的是第二条指令。

小智 5

mov是一个“移动”指令。linmovl意味着它对“长”值(在您的情况下为 32 位)进行操作。%espin周围的括号(%esp)表示它不应该移动寄存器的内容%esp,而是应该在寄存器中的地址处加载内存%esp4in4(%esp)指的是在取消引用之前添加的偏移量%esp

因此该指令从地址加载 32 位值%esp + 4并将其存储在寄存器中%eax

因为在 x86 中,所有函数参数都存储在线程堆栈上(大多数情况下,可以使用其他调用约定),所以该指令将函数参数加载到寄存器中%eax

在 C 中,参数以相反的顺序推送(从最后一个到第一个),因此它加载第一个参数。

看来原始函数是在 C 中定义的,如下所示:

int fct(int val);
Run Code Online (Sandbox Code Playgroud)

指令jg是为有符号的更大比较生成的,所以第一行似乎是

if (val > 0)
   ...
Run Code Online (Sandbox Code Playgroud)