平时工作中有接触到汇编,一时兴起,就想看看GNU的编译器生成的汇编代码是什么样的。
1. 生成汇编代码
我写了一个非常简单的C语言代码,如下
然后,执行“gcc -S simple_program.s simple_program.c”生成汇编代码(simple_program.s)。
如下是注释了的汇编代码,编译器生成的汇编代码是没有注释的。
2. 汇编的知识,再说几点
在汇编代码中,我增加了不少注释。有些问题,我觉得光靠注释是说不清楚的,这里简明交待两点。
2.1 汇编程序中的segment问题
在汇编程序中,不同的数据是放在不同的段中的。
代码是放在代码段中的,就是.text段中。
数据是放在数据段中的,数据段有.data段和.bss段之分。赋了初值的全局变量放在.data段中,没有赋初值的全局变量放在.bss段中。
2.2汇编程序中的函数调用问题
汇编代码是由GNU编译器自动生成的。虽然是自动的,肯定有一个约定成俗的规范在起作用,要么岂不乱套了。
函数调用的规范,或许你从汇编代码中已经看出了一点端倪。
先说一下函数参数。函数参数是通过栈空间来传递的。
在调用函数之前,先将函数参数入栈,进栈的顺序依次为,函数参数n,函数参数n-1, ........函数参数1。
在汇编程序执行call function_name后,汇编程序会自行将函数的返回地址,也就是call function_name的下一行的指令地址压入栈中。
在汇编函数中,为了保证返回地址不被意外的更改,将EBP压入栈中,专门用EBP保存ESP的值。
这样,在汇编函数中,函数参数1就保存在ESP+8的位置处,函数参数2保存在ESP+12的位置处,依次类推。ESP+0保存的是EBP的值,ESP+4保存的是函数的返回地址。
汇编函数的返回值入在寄存器EAX中。
局部变量也是通过栈来实现的。
文章写得简略。若有不明之处。还请见谅。
版权声明:本文为博主原创文章,未经博主允许不得转载。