以下代码
int _main() {return 0;}
使用命令编译:
gcc -s -nostdlib -nostartfiles 01-simple.c -o01-simple.exe
gcc版本4.4.1(TDM-1 mingw32)
OllyDbg产生了这个输出:
你能解释一下这里发生了什么吗? 到目前为止的分析:
// these two seems to be an idiom:
PUSH EBP // places EBP on stack
MOV EBP, ESP // overwrites EBP with ESP
MOV EAX, 0 // EAX = 0
LEAVE // == mov esp, ebp
// pop ebp
// according to
// http://en.wikipedia.org/wiki/X86_instruction_listings
这一切的含义是什么?
答案 0 :(得分:5)
这会创建一个stack frame。
PUSH EBP
MOV EBP, ESP
在使用的调用约定中,返回值通过EAX
发回(因此您0
是因为您编写了return 0;
- 尝试将其更改为return 1;
并看看它如何影响代码。)
MOV EAX, 0
这告诉处理器清理堆栈帧(相当于MOV ESP, EBP
后跟POP EBP
,这与创建堆栈帧时的操作相反):
LEAVE
答案 1 :(得分:1)
指令在运行时加载程序进入int _main()
函数
PUSH EBP MOV EBP, ESP
设置堆栈帧并访问参数(如果提供的参数)将从EBP
+参数大小(WORD,BYTE,LONG等)偏移。
通常EAX
寄存器是将退出状态从运行时环境返回到操作系统加载器的普通寄存器,
MOV EAX, 0 LEAVE换句话说,就是说程序已经退出成功地将0返回给操作系统。
在使用返回的情况下,在将控制权交还给操作系统之前,在运行时执行时会恢复堆栈帧。
POP EBP
普遍的共识是,如果发生错误,该值将为非零,并且可以用于批处理文件(回溯到旧的DOS天)和unix脚本,它会检查程序是否成功运行或不继续,然后继续,具体取决于批处理文件或脚本的性质。
答案 2 :(得分:0)
'MOV EAX,0'指令是你函数的主体。标题代码用于设置代码运行的空间。
'LEAVE'指令将代码返回到它的位置。即使您没有说标准库,但链接器中还有很多其他代码。