汇编代码、printf 和在堆栈上分配空间[重复]

问题描述 投票:0回答:1

我正在为 Pentium 编写 64 位汇编代码。我正在使用 Microsoft Visual C/C++ 和 MASM。在汇编代码中,我编写了以下代码片段来调用

printf

push    rcx
push    rdx
push    rdi
push    rsi

lea rcx,string1
call    printf

pop rsi
pop rdi
pop rdx
pop rcx

其中 string1 定义为:

string1   db  "start of func", 10, 0

我预计前四条指令会在堆栈上保存四个寄存器。也就是说,保存的寄存器的值将由四个

pop
指令恢复。然而,寄存器值没有被正确恢复。我找到了这个视频:

调用 printf 的链接

该视频表示,在调用

printf
之前,您需要在堆栈上为这些值分配 32 个字节。因此,我写了这段代码:

push    rcx
push    rdx
push    rdi
push    rsi

sub rsp,20
lea rcx,string1
call    printf
add rsp,20h

pop rsi
pop rdi
pop rdx
pop rcx

这段代码有效并且对我来说有一定意义。当我查看 C 编译器生成的代码时,它没有在堆栈上分配任何额外的空间并且它可以工作。因此,我不明白为什么需要在堆栈上分配额外的空间。请告诉我我缺少什么。

c assembly x86 stack
1个回答
0
投票

从您在

rcx
中传递值的事实来看,您似乎正在使用 Windows 调用约定,而不是除 microsoft 之外的每个人都使用的“标准”调用约定。

对于 Windows x64 调用约定,当调用 varargs 函数(

printf
)时,您必须在返回地址上方的堆栈上分配 32 字节的“影子”空间。

© www.soinside.com 2019 - 2024. All rights reserved.