C语言的Hello World的汇编剖析(64位 Intel架构)
文章目录
一. 前提准备
-
Linux虚拟机
-
Gcc编译器(若采用Linux虚拟机剖析,则自带无需下载)
-
C语言的Hello World代码
#include <sudio.h> int main(){ printf("Hello World!"); return 1; }
二. C转换为汇编操作准备
2.1 创建目录&复制代码
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ICWamy6-1681804213620)(C语言的Hello World的汇编剖析.assets/操作1.png)]](https://i-blog.csdnimg.cn/blog_migrate/3e078c65f006cb37b721d24d7e547770.png)
2.2 C文件转换为汇编文件
若将C文件转换为汇编文件,则需要编译器作为桥梁,这里使用gcc编译器,由于为只需编译成汇编文件,所以采用—S这个选项命令即可
zhp@root:~$ gcc --help
....
-S Compile only; do not assemble or link.
....
汇编文件如图所示
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oMfO10f4-1681804213620)(C语言的Hello World的汇编剖析.assets/操作2.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKexEwag-1681804213621)(C语言的Hello World的汇编剖析.assets/操作3.png)]](https://i-blog.csdnimg.cn/blog_migrate/b4aec1255fb617ea5b1532ac6435d1f1.png)
三. 剖析汇编文件
前提概要:
- b:1字节,8bit
- w:2字节,16bit
- l:4字节,32bit
- q:8字节,64bit
Hello World所经历的步骤剖析:
- 栈空间的开辟,使栈基址指向新空间基址,并让栈针sp定位道栈基址bp位置
- 并通过Hello World字符串地址值存放edi寄存器
- 调用printf函数打印Hello World
- 返回值保存寄存器中
- 还原bp
- 还原栈空间,sp还原

ps:查看输出Hello World
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kr7LrxsU-1681804213621)(C语言的Hello World的汇编剖析.assets/操作5.png)]](https://i-blog.csdnimg.cn/blog_migrate/2e1dbc4396e6ecb285534b7421ecccec.png)
四. 指令相关
ret指令:
- 弹出返回地址值并保存到指令地址寄存器
- 通过可选项n,从栈中释放参数
- 恢复调用过程
下图截至intel手册Volume 3 6.4节

五. 额外记录:指令段相关调用
就如Hello World的输出
OS正在运行自身程序,突然来了C语言一段代码,调用它
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GPlQIRuq-1681804213621)(C语言的Hello World的汇编剖析.assets/image-20230418153040035.png)]](https://i-blog.csdnimg.cn/blog_migrate/64f0e150c66659a50f096171ec5d7adc.png)
详细步骤分析
- 指令段A首先需要调用call命令,来调用指令段B
- 这时需要先开辟栈空间等一系列操作,上方已经讲过,不在赘述
- 当调用后,需要返回到指令段A继续执行,这时需要用到ret指令
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FUn6pB7B-1681804213622)(C语言的Hello World的汇编剖析.assets/image-20230418153853525.png)]](https://i-blog.csdnimg.cn/blog_migrate/397ddc13a241453936ee299dc3c38dd4.png)
指令段之间的调用,若有参数传递时,则会有2种方式
- 一种是存储到一个公共地方,即通用寄存器
- 另一种通过栈本身特性,为指令段A的数据开辟一段栈帧,指令段B通过bp的pop/其他方式,来获取数据
第二种方式的操作非常耗时,但也不是抛弃这个方式,由于寄存器数量有限(和计算机的位数相关,如你的计算机是32位,则有32个寄存器),当通用寄存器耗尽时,就可采用此方式。
⭐️更详细的指令间参数调用可参考:指令段间及文件间参数调用过程(64位 Intel架构)
本文介绍了在64位Intel架构上,将C语言的HelloWorld程序转换为汇编代码的过程,并详细剖析了栈空间管理、printf函数调用以及ret指令在返回过程中的作用。文章还探讨了指令段间的调用机制,包括参数传递的方式。
1072

被折叠的 条评论
为什么被折叠?



