免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6231 | 回复: 19
打印 上一主题 下一主题

[C] main函数汇编原理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-12-06 17:00 |只看该作者 |正序浏览
main函数代码:
int main()
{return 0;}
虚拟机中反编译main函数源码:
0x08048354 <main+0>:    lea    0x4(%esp),%ecx
0x08048358 <main+4>:    and    $0xfffffff0,%esp
0x0804835b <main+7>:    pushl  -0x4(%ecx)
0x0804835e <main+10>:   push   %ebp
0x0804835f <main+11>:   mov    %esp,%ebp
0x08048361 <main+13>:   push   %ecx
0x08048362 <main+14>:   mov    $0x0,%eax
0x08048367 <main+19>:   pop    %ecx
0x08048368 <main+20>:   pop    %ebp
0x08048369 <main+21>:   lea    -0x4(%ecx),%esp
0x0804836c <main+24>:   ret  
请教高手分析下指令含义,指点迷津。

论坛徽章:
0
20 [报告]
发表于 2010-12-07 20:35 |只看该作者
对于lz这段特定的代码,lz 也可以理解为:  寄存器ecx也有可能用作其它用途(代码复杂的情况下),因此用  p ...
system888net 发表于 2010-12-07 18:42

非常感谢你的解答,如果你能给出例子那就更好了。
我之前的编译环境是虚拟机中gcc 4.1.2,我重新在gcc 4.5.1(实体机)中编译代码的得:
0x08048394 <+0>:     push   %ebp
0x08048395 <+1>:     mov    %esp,%ebp
0x08048397 <+3>:     mov    $0x0,%eax
0x0804839c <+8>:     pop    %ebp
0x0804839d <+9>:     ret
或许这才是简洁的汇编码。

论坛徽章:
0
19 [报告]
发表于 2010-12-07 19:45 |只看该作者
回复  BJSH
我想请教的是调用者指针的功能本身就由
lea    -0x4(%ecx),%esp
这一句指令来完成了,为什么 ...
Anno_Domini 发表于 2010-12-07 14:33



我觉得没啥用处, 实际上也根本没用到。

gcc 4.4.3 的汇编:

.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        movl    $0, %eax
        popl    %ebp
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

论坛徽章:
0
18 [报告]
发表于 2010-12-07 18:42 |只看该作者
本帖最后由 system888net 于 2010-12-07 18:43 编辑
回复  BJSH
为什么还要pushl -0x4(%ecx) ?Anno_Domini 发表于 2010-12-07 14:33


对于lz这段特定的代码,lz 也可以理解为:  寄存器ecx也有可能用作其它用途(代码复杂的情况下),因此用  pushl -0x4(%ecx)  保存在一个固定的位置.

论坛徽章:
0
17 [报告]
发表于 2010-12-07 18:21 |只看该作者
本帖最后由 system888net 于 2010-12-07 18:24 编辑

对于源代码到执行代码,编译器目的是可以实际正确的执行,因此方法上可以多种实现选择(目的上也有一些小分支), 对于lz说的这个例子,正常情况下没有  pushl -0x4(%ecx)  也没有影响.
参考另一个编译器的结果:
   注: 这个编译器参用了寄存器(edi,rsi)传递参数(argc,argv).

  1.         pushq        %rbp
  2.         movq        %rsp, %rbp
  3.         movl                %edi, -4(%rbp)
  4.         movq        %rsi, -16(%rbp)
  5.         movl                $0, %eax
  6.         leave
  7.         ret
复制代码

论坛徽章:
0
16 [报告]
发表于 2010-12-07 18:07 |只看该作者
本帖最后由 system888net 于 2010-12-07 18:11 编辑
回复  BJSH
我想请教的是调用者指针的功能本身就由
lea    -0x4(%ecx),%esp
这一句指令来完成了,为什么还要pushl -0x4(%ecx) ?Anno_Domini 发表于 2010-12-07 14:33


    lz 善于思考.

论坛徽章:
0
15 [报告]
发表于 2010-12-07 14:33 |只看该作者
回复 13# BJSH
我想请教的是调用者指针的功能本身就由
lea    -0x4(%ecx),%esp
这一句指令来完成了,为什么还要pushl -0x4(%ecx) ?

论坛徽章:
0
14 [报告]
发表于 2010-12-07 14:14 |只看该作者
本帖最后由 liwangli1983 于 2010-12-07 14:33 编辑
关于ECX的解释 有误。

ECX 保存了 传递给main函数的 ARGC的地址, 也相当于保存了原ESP, 不过要-0x4

...
BJSH 发表于 2010-12-07 13:42



    没错确实搞乱了.如你所说push的是返回地址.这样最后一个pop后指针指向的正是返回地址,这时ret正好可以从esp中取出返回地址并回到上级.

    ecx保存的是argc的地址......昨晚写的时候手边没有纸笔,没画一下栈就写,果然错了不少地方

论坛徽章:
0
13 [报告]
发表于 2010-12-07 13:42 |只看该作者
关于ECX的解释 有误。

ECX 保存了 传递给main函数的 ARGC的地址, 也相当于保存了原ESP, 不过要-0x4

pushl  -0x4(%ecx)   ; push到栈里的是调用函数的IP地址

论坛徽章:
0
12 [报告]
发表于 2010-12-07 09:31 |只看该作者
6楼很给力
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP