本文链接:
http://blog.163.com/strive_only/blog/static/89380168201192894043752/
首先编写一个C语言程序code.c,包含的过程定义如下:
命令行上使用"-S"选项就能得到C语言编译器产生的汇编代码:
这会使GCC运行编译器,生成一个汇编文件code.s,汇编程序包含如下代码:
使用“-c”命令行选项,GCC会编译汇编该代码:
在文件code.o上运行GNU调试工具GDB,输入命令:
(gdb) x/17xb sum
告诉GDB检查(简写为x)17个十六进制格式的字节(简写为b)
查查看上档代码文件的内容,最有价值的是反汇编器,它可以根据目标代码产生一种于汇编代码的格式。Linux系统中,带“-d”命令行的程序OBJDUMP可以充当这个角色:
unix>objdump -d code.o
结果如下:
其中,左边是按照前面的字节顺序排列的17个十六进制字节值,它们分成了几组,每组有1~6个字节。每组都是一条指令,右边是等价的汇编语言。
值得注意,反汇编器使用的指令命名规则与GCC生成的汇编代码使用的有些细微的差别。上面示例中,省略了很多指令结尾的“l”。这些后缀是大小指示符,大多情况下可以忽略。
继续书写main.c代码:
使用命令生成可执行文件prog:
反汇编prog文件:
unix>objdump -d prog
反汇编器会抽取出各种代码序列,包括下面这个段:
这段代码与code.c反汇编生成的几乎完全一样。其中一个主要区别是櫣列出的地址不同——链接器将代码的地址移到一段不同的地址范围中。第二个不同之处在于链接器确定了存储全局变量accum的地址。
首先编写一个C语言程序code.c,包含的过程定义如下:
int accum = 0; int sum (int x, int y) { int t = x+y; accum +=t; return t; } |
![gcc笔记 - strive_only - 奋斗,我要一直奋斗...等你...](http://img6.ph.126.net/BpWMFFPeMkmveza0ptUtjA==/563231428415064296.png)
![gcc笔记 - strive_only - 奋斗,我要一直奋斗...等你...](http://img0.ph.126.net/Imh4S6PJ-vv3F1_cigSk_Q==/2686115702766833450.png)
使用“-c”命令行选项,GCC会编译汇编该代码:
![gcc笔记 - strive_only - 奋斗,我要一直奋斗...等你...](http://img7.ph.126.net/eD4jFSJQJ-EOWnql44oxSw==/2760706571595158277.png)
(gdb) x/17xb sum
告诉GDB检查(简写为x)17个十六进制格式的字节(简写为b)
![gcc笔记 - strive_only - 奋斗,我要一直奋斗...等你...](http://img1.ph.126.net/bF7bBLlHBhmp1nPxLhg1Iw==/2491335018883065611.png)
unix>objdump -d code.o
结果如下:
![gcc笔记 - strive_only - 奋斗,我要一直奋斗...等你...](http://img3.ph.126.net/hEuSOxONXKY0gZjHM27Lpw==/2491335018883065653.png)
值得注意,反汇编器使用的指令命名规则与GCC生成的汇编代码使用的有些细微的差别。上面示例中,省略了很多指令结尾的“l”。这些后缀是大小指示符,大多情况下可以忽略。
int main() { return sum(1, 3); } |
![gcc笔记 - strive_only - 奋斗,我要一直奋斗...等你...](http://img5.ph.126.net/Wsfp4x-252wPB_RiJfnvwA==/188588234413185715.png)
unix>objdump -d prog
反汇编器会抽取出各种代码序列,包括下面这个段:
![gcc笔记 - strive_only - 奋斗,我要一直奋斗...等你...](http://img6.ph.126.net/UzFaLAzzmI__k5Y2mtHFmw==/2552696563805985126.png)
这段代码与code.c反汇编生成的几乎完全一样。其中一个主要区别是櫣列出的地址不同——链接器将代码的地址移到一段不同的地址范围中。第二个不同之处在于链接器确定了存储全局变量accum的地址。