【发布时间】:2021-06-08 20:06:06
【问题描述】:
在以下 C 代码中:
#include <stdio.h>
int main(void){getchar();}
它产生以下汇编:
main:
push rbp
mov rbp, rsp
# no extra instruction here when header is included
call getchar
mov eax, 0
pop rbp
ret
但是,如果我不在文件中包含 stdio.h,那么它仍然可以编译,但会添加看起来像随机的 mov eax, 0 指令:
这是编译器资源管理器:https://godbolt.org/z/3fTcss。这只是“未定义行为”的一部分,还是有特殊原因将call getchar 之前的指令添加到那里?
【问题讨论】:
-
如果没有原型,编译器会生成代码来处理 varargs 函数以确保安全,这意味着将
al归零。 -
@Jester:我认为这意味着我不能一次将 256 个数字传递给 snprintf。
-
你可以。
al仅表示使用的向量寄存器的数量,最大为 8 (xmm0-xmm7)。其余参数进入堆栈。 -
我想知道为什么编译器不使用
xor来清除eax。 -
@SimonRichter 确实如此,
-O2及以上。mov其中的零只是未优化的、明显的、接近 C 的版本。
标签: c assembly x86-64 calling-convention