【发布时间】:2015-09-17 22:20:18
【问题描述】:
我正在尝试反汇编简单 C 程序的 clang 二进制文件(使用 -O0 编译),我对生成的特定指令感到困惑。
这里有两个带有标准参数的空 main 函数,其中一个返回值,另一个不返回:
// return_void.c
void main(int argc, char** argv)
{
}
// return_0.c
int main(int argc, char** argv)
{
return 0;
}
现在,当我分解它们的程序集时,它们看起来相当不同,但有一行我不明白:
return_void.bin:
(__TEXT,__text) section
_main:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp, %rbp
0000000000000004 movl %edi, -0x4(%rbp)
0000000000000007 movq %rsi, -0x10(%rbp)
000000000000000b popq %rbp
000000000000000c retq
return_0.bin:
(__TEXT,__text) section
_main:
0000000100000f80 pushq %rbp
0000000100000f81 movq %rsp, %rbp
0000000100000f84 xorl %eax, %eax # We return with EAX, so we clean it to return 0
0000000100000f86 movl $0x0, -0x4(%rbp) # What does this mean?
0000000100000f8d movl %edi, -0x8(%rbp)
0000000100000f90 movq %rsi, -0x10(%rbp)
0000000100000f94 popq %rbp
0000000100000f95 retq
只有在我使用函数时才会生成不是void,所以我认为它可能是另一种返回0的方式,但是当我更改返回的常量时,这一行根本没有改变:
// return_1.c
int main(int argc, char** argv)
{
return 1;
}
empty_return_1.bin:
(__TEXT,__text) section
_main:
0000000100000f80 pushq %rbp
0000000100000f81 movq %rsp, %rbp
0000000100000f84 movl $0x1, %eax # Return value modified
0000000100000f89 movl $0x0, -0x4(%rbp) # This value is not modified
0000000100000f90 movl %edi, -0x8(%rbp)
0000000100000f93 movq %rsi, -0x10(%rbp)
0000000100000f97 popq %rbp
0000000100000f98 retq
为什么会生成这条线,它的目的是什么?
【问题讨论】:
-
您是否使用普通函数(即不称为 main 的函数)对此进行了测试?
-
main没有int返回类型违反了托管环境的标准。不要期望任何特定的行为。 -
你禁止 clang 删除无用的代码(
-O0)。为什么要询问程序集中的奇怪代码?
标签: c assembly clang disassembly calling-convention