免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6227 | 回复: 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
2 [报告]
发表于 2010-12-06 17:12 |只看该作者
学过一点汇编,但是分析就不会了~

论坛徽章:
0
3 [报告]
发表于 2010-12-06 19:49 |只看该作者
回复 1# Anno_Domini


   {:3_190:}在某个 ARM bootloader里发现main的参数用通用寄存器的1号和2号来传递,进去之后就是保存这2个参数.而且这里还有个标准XXX,就是一个编译器的规定,汇编调用C的规则,所以要先看看编译的规则才知道

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
4 [报告]
发表于 2010-12-06 20:50 |只看该作者
压栈,运算,出栈,再压栈,再运算,再出栈。。。

论坛徽章:
0
5 [报告]
发表于 2010-12-06 21:12 |只看该作者
楼主可以看看《程序员的自我修养》这本书里介绍得很好

论坛徽章:
0
6 [报告]
发表于 2010-12-06 22:35 |只看该作者
本帖最后由 liwangli1983 于 2010-12-07 14:30 编辑

0x08048354 <main+0>:    lea    0x4(%esp),%ecx
0x08048358 <main+4>:    and    $0xfffffff0,%esp            ##让栈指针按16字节对齐
0x0804835b <main+7>:    pushl  -0x4(%ecx)                  ##返回地址入栈
0x0804835e <main+10>:   push   %ebp                          ##保存栈帧指针值
0x0804835f <main+11>:   mov    %esp,%ebp                 ##栈帧指针指向栈指针指向的位置
0x08048361 <main+13>:   push   %ecx                           ##ecx入栈
0x08048362 <main+14>:   mov    $0x0,%eax                  ##将main的返回值放入eax
0x08048367 <main+19>:   pop    %ecx                            ##ecx出栈
0x08048368 <main+20>:   pop    %ebp                           ##恢复栈帧指针值
0x08048369 <main+21>:   lea    -0x4(%ecx),%esp          ##恢复原栈指针值
0x0804836c <main+24>:   ret                                           ##返回(ret会自动把esp指向的位置的内容复制到pc中.因为此时esp指向<main+7>时入栈的返回地址,所以此句返回)

大部分普通函数基本上都是从push %ebp开始的.这里两次把返回地址入栈(第一次是调用main的程序入的,就放在刚刚进入main过程时esp指向的位置),第二次大约是因为对栈指针取16字节对齐可能导致栈指针变化,所以重新入栈一次返回地址,再像正常子过程那样把ebp入栈.这样在程序末尾pop %ebp后,%esp就自然指向返回地址了,否则esp指向的内容是不确定的.

如果可能最好把<C语言标准与实现>啃下来,很硬的书,通篇汇编和各种类型数值的分析,看着很容易犯困。但内容确实很不错,认真看下来收获不小。

论坛徽章:
0
7 [报告]
发表于 2010-12-06 23:49 |只看该作者
回复 6# liwangli1983

谢谢你的指点,但还是有一个不明白的地方:
0x08048369 <main+7>:    pushl  -0x4(%ecx) 这一句好像没有什么实际用处啊,并且为什么函数到最后也没有pop它?

论坛徽章:
0
8 [报告]
发表于 2010-12-06 23:52 |只看该作者
回复 6# liwangli1983

哦,其实那一句不用pop,函数最后返回时就已经后退到原始栈帧了。但至于其用处还是不得而知,再请教一下c语言标准与实现,哪儿可以获得?

论坛徽章:
0
9 [报告]
发表于 2010-12-07 08:35 |只看该作者
回复  liwangli1983

谢谢你的指点,但还是有一个不明白的地方:
0x08048369 :    pushl  -0x4(%ecx) 这 ...
Anno_Domini 发表于 2010-12-06 23:49


嘛正常编译是有很多无用代码的,加上O2也许就优化掉了.

论坛徽章:
0
10 [报告]
发表于 2010-12-07 08:36 |只看该作者
回复  liwangli1983

哦,其实那一句不用pop,函数最后返回时就已经后退到原始栈帧了。但至于其用处还是 ...
Anno_Domini 发表于 2010-12-06 23:52



    C语言标准与实现到处可以下到啊,这个本来就只有电子版.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP