混淆大会CALL,RET语句

时间:2014-08-11 10:06:34

标签: assembly stack nasm masm

我想知道" CALL"指令执行。它首先在堆栈或函数参数上推送返回地址吗?

由于

2 个答案:

答案 0 :(得分:7)

CALL根本不会推动参数。它只推送返回地址。你有责任自己推动论证,这显然发生在CALL之前。例如:

    push 2
    push 1
    push "%d"
    call printf
next_instruction:
    add esp, 12

当进入printf函数时,假设接近32位的调用,堆栈将如下所示:

esp+0:  address of next_instruction
esp+4:  address of "%d"
esp+8:  1
esp+12: 2

编辑:关于参数的顺序,扩展了@Martin所说的内容:

对堆栈中的内容的解释是调用者和被调用者之间的契约(名为'调用约定'),它取决于很多东西,包括语言,架构,编译器等。对于x86上的C,参数从最后一个推送到第一个。所以上面的汇编代码段对应于翻译的C语句:

printf("%d", 1, 2);

如果你看一下上面的堆栈,你会看到,因为我们按相反的顺序推送了参数,所以它们从第一个到最后一个相对于esp被排序。这种方式printf可以读取第一个参数"%d",而不知道将跟随多少参数,然后从格式字符串中确定其余参数。此外,因为在C调用约定中,调用者负责从堆栈中删除参数(next_instruction),传递多于必要的参数是无害的(尽管根据标准它是未定义的行为)。

答案 1 :(得分:2)

如果函数返回的对象太大而无法放入寄存器,则预先分配返回对象的空间:

        sub     esp,sizeof object
        push    ecx
        push    eax
        call    example
        add     esp,8     ;restore stack
;                         ;esp is now pointer to object
        add     esp,sizeof object    ;restore stack once object no longer needed