3

以下代码

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

这一切的意义是什么?

4

3 回答 3

5

这将创建一个堆栈帧

PUSH EBP      
MOV EBP, ESP  

在使用的调用约定中,返回值是通过发送回EAX的(所以0因为你写了return 0;- 尝试将其更改为return 1;并查看它如何影响代码)。

MOV EAX, 0 

这告诉处理器清理堆栈帧(它相当于MOV ESP, EBP随后POP EBP是与创建堆栈帧时所做的相反):

LEAVE
于 2010-05-25T00:19:22.280 回答
1

int _main()指令在运行时加载程序进入函数时设置堆栈帧,

推送 EBP
MOV EBP,ESP

设置堆栈帧并访问参数(如果提供任何参数)将偏移EBP+ 参数的大小(WORD、BYTE、LONG 等)。

通常EAX寄存器是从运行时环境返回退出状态给操作系统加载器的正常寄存器,

移动 EAX, 0
离开

换句话说,就是说程序已经成功退出,向操作系统返回一个 0。

在使用返回的情况下,堆栈帧会在运行时执行时恢复,然后再将控制权交还给操作系统。

POP EBP

一般的共识是,如果发生错误,该值将不为零,并且可以从批处理文件(回到旧的 DOS 时代)和用于检查程序是否成功运行的 unix 脚本中使用,并且根据批处理文件或脚本的性质继续。

于 2010-05-25T00:25:16.813 回答
0

'MOV EAX,0' 指令是函数的主体。标头代码用于为代码运行设置空间。

'LEAVE' 指令将您的代码返回到它所在的位置。即使您说没有标准库,链接器也会在其中放置许多其他代码。

于 2010-05-25T00:25:10.183 回答