【发布时间】:2017-11-21 19:50:18
【问题描述】:
我正在尝试查找从 c 程序生成的汇编代码的含义。这是C语言的程序:
int* a = &argc;
int b = 8;
a = &b;
这是生成的带有解释的汇编代码。有一点不明白:
主要序幕:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
在%eax中加载argc的地址:
movl %ecx, %eax
我没有得到的部分:
movl 4(%eax), %edx
movl %edx, -28(%ebp)
Stack-Smashing Protector 代码(设置):
movl %gs:20, %ecx
movl %ecx, -12(%ebp)
xorl %ecx, %ecx
在 a 和 b 中加载值(参见 main.c):
movl %eax, -16(%ebp)
movl $8, -20(%ebp)
修改a的值(a = &b):
leal -20(%ebp), %eax
movl %eax, -16(%ebp)
Stack-Smashing Protector 代码(验证堆栈是否正常):
movl $0, %eax
movl -12(%ebp), %edx
xorl %gs:20, %edx
je .L7
call __stack_chk_fail
如果堆栈正常:
.L7:
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
所以我不理解的部分是修改 -28(%ebp) 中的值,这是一个从未使用过的地址。有人知道为什么会生成这部分吗?
【问题讨论】:
-
如果您在没有优化的情况下进行编译(默认),那么即使不需要,编译器输出也会包含所有加载/存储到内存中的内容。将您的代码放入不是
main的函数中,并在 (-O3) 上使用优化进行编译 -
不要使用 main(),让您的代码在测试中使用其他函数名称。 main() 问题已被问及回答了无数次......
-
您告诉编译器通过不指定优化标志来关闭其大脑,现在您想知道它会生成奇怪的代码吗?
-
如果我使用 -O1 进行优化,唯一剩下的就是 mov $0, %eax 然后 ret
-
@DJ_Joe 真该死。如果您想强制编译器发出无用的代码,请使用
volatile。或者编写一些实际做一些有意义的工作的测试用例,编译器不能简单地删除。