【发布时间】:2017-12-22 22:53:55
【问题描述】:
这是一个hello world程序的示例代码:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
这是我得到的目标文件的反汇编:
File Type: COFF OBJECT
main:
0000000000000000: 48 83 EC 28 sub rsp,28h
0000000000000016: C3 ret
__local_stdio_printf_options:
0000000000000000: 48 8D 05 00 00 00 lea rax,[?_OptionsStorage@?1??__local_stdio_printf_options@@9@9]
00
0000000000000007: C3 ret
_vfprintf_l:
0000000000000000: 4C 89 4C 24 20 mov qword ptr [rsp+20h],r9
0000000000000014: 48 83 EC 38 sub rsp,38h
0000000000000018: E8 00 00 00 00 call __local_stdio_printf_options
0000000000000039: E8 00 00 00 00 call __stdio_common_vfprintf
000000000000003E: 48 83 C4 38 add rsp,38h
0000000000000042: C3 ret
printf:
0000000000000000: 48 89 4C 24 08 mov qword ptr [rsp+8],rcx
0000000000000027: E8 00 00 00 00 call __acrt_iob_func
000000000000002C: 4C 8B 4C 24 28 mov r9,qword ptr [rsp+28h]
000000000000003C: E8 00 00 00 00 call _vfprintf_l
0000000000000041: 89 44 24 20 mov dword ptr [rsp+20h],eax
000000000000004E: 8B 44 24 20 mov eax,dword ptr [rsp+20h]
0000000000000056: C3 ret
在printf 函数中,我们还有两个函数调用:__acrt_iob_func 和_vfprintf_l。
第一个函数具体是做什么的?
我们如何在目标文件中拥有
_vprintf_l函数?
请提供详细解释。
编译: cl /TC main.cpp
反汇编为: dumpbin /disasm main.obj
PS:我删除了部分汇编代码,以便我可以发布问题。
【问题讨论】:
-
sub rsp,28h/ret因为main的整个主体是零意义。如果您将此目标文件链接到可执行文件并运行它,它就不会是实际运行的内容,因为它只会崩溃(除非某些东西使用jmp以低于当前rsp值的返回地址输入main,但是Windows ABI 没有红色区域...) -
@PeterCordes 你仔细阅读了这个问题吗?
-
哦,您是否手动编辑它而不留下
...或; comment?你说的“PS”就是这个意思吗?哦,我猜是这样,这可以解释main中这些指令地址的不连续性。我建议留在main中的call指令中,这样就不会分散注意力,并且对于那些好奇实际上以什么顺序调用哪个辅助函数的人来说。 -
您删除的汇编代码使您发布的内容变得毫无意义
-
这真的不是一个很好的第一个程序开始:我想看看程序的汇编。尝试类似 int fun ( int x, int y ) { return (x+y+4); } assemble 反对反汇编。然后变得更复杂,但一开始调用库函数并不是那么有趣。了解调用和返回的基础知识以及简单的操作。
标签: c assembly visual-c++ x86 msvcrt