作者云青转载原创作品请注明出处汇编基础知识:movl,subl,pushl,topl,ret,addl,leave,enter参考资料下载地址。http://pan.baidu.com/s/1cdISDC课程地址:《Linux内核分析》MOOC课程http://mooc.study.163.com/cou...1.准备创建文件并编译intg(intx){returnx+3;}intf(intx){returng(x);}intmain(void){returnf(8)+1;}编译命令:gcc-S-odemo1.sdemo1.c-m32运行后,生成以下文件:.file"demo1.c".text.globlg.typeg,@functiong:.LFB0:.cfi_startprocpushl%ebp.cfi_def_cfa_offset8.cfi_offset5,-8movl%esp,%ebp.cfi_def_cfa_register5movl8(%ebp),%eaxaddl$3,%eaxpopl%ebp.cfi_restore5.cfi_def_cfa4,4ret.cfi_endproc.LFE0:.sizeg,.-g.globlf复制代码.typef,@functionf:.LFB1:.cfi_startprocpushl%ebp.cfi_def_cfa_offset8.cfi_offset5,-8movl%esp,%ebp.cfi_def_cfa_register5subl$4,%espmovl8(%ebp),%eaxmovl%eax,(%esp)调用g离开.cfi_restore5.cfi_def_cfa4,4ret.cfi_endproc.LFE1:.sizef,.-f.globlmain.typemain,@functionmain:.LFB2:.cfi_startprocpushl%ebp.cfi_def_cfa_offset8.cfi_offset5,-8movl%esp,%ebp.cfi_def_cfa_register5subl$4,%espmovl$8,(%esp)调用faddl$1,%eax离开.cfi_restore5.cfi_def_cfa4,4ret.cfi_endproc.LFE2:.sizemain,.-main.ident"GCC:(Ubuntu4.8.4-2ubuntu1~14.04.3)4.8.4".section.note.GNU-stack,"",@progbits我们简化了命令以获得以下汇编指令:g:pushl%ebpmovl%esp,%ebpmovl8(%ebp),%eaxaddl$3,%eaxpopl%ebpretf:pushl%ebpmovl%esp,%ebpsubl$4,%espmovl8(%ebp),%eaxmovl%eax,(%esp)callg离开retmain:pushl%ebpmovl%esp,%ebpsubl$4,%espmovl$8,(%esp)callfaddl$1,%eaxleaveret备注:%开头表示寄存器$$开头表示立即数()表示间接寻址,例子(GAS=C语言):(%eax)=*eax[[2]](http://www.cnblogs.com/lxgeek...Imm(Ea),索引寻址,样本(GAS=Clanguage):4(%eax)=*(4+eax)2.汇编指令执行流程分析下面以简化版为例:C语言是从mian函数开始运行的。同样,汇编也是从main函数开始运行的。接下来我们从main函数开始,首先执行18行的pushl指令。首先画出此时的内存栈:此时esp和ebp都指向栈底。pushl%ebx,即将数据压栈,该指令相当于subl$4,%espmovl%ebx,(%esp)执行完pushl%ebp,eip指向下一条指令,变为:2.执行movl%esp,%ebp,然后eip指向下一条指令,变成3,执行subl$4,%esp4,执行movl$8,(%esp)5,callfcallf相当于pushl%eipmovlf%eip6,pushl%ebp7,movl%esp,%ebp8,subl$4,%esp9,movl8(%ebp),%eax10,movl%eax,(%esp)11,callg12,pushl%ebpmovl%esp,%ebp会执行这些每次他们输入一个函数时都会有两条汇编指令。两步操作是归一化步骤,称为序言[1]。当函数执行时,程序集会生成一个栈调用帧:具体如下://构建被调用函数的栈帧pushl%ebpmovl%esp,%ebp//被调用函数体//dosomething//移除被调用函数的栈帧movl%ebp,%esppopl%ebpret13,movl8(%ebp),%eax14,addl$3,%eax15,popl%ebppopl%ebp等价于movl(%esp),%ebpaddl$4,%esb16,ret相当于popl%eip17,leave相当于movl%ebp,%esppopl%ebp18,ret19,addl$1,%eax20leave21,retmain函数运行结束后,返回%eax的值,即12篇参考文章:[1]X86汇编调用框架浅析及CFI介绍[2]http://www.cnblogs.com/lxgeek...
