C语言的Hello World的汇编剖析(64位 Intel架构)

C语言的Hello World的汇编剖析(64位 Intel架构)

文章目录

  • C语言的Hello World的汇编剖析(64位 Intel架构)
    • 一. 前提准备
    • 二. C转换为汇编操作准备
      • 2.1 创建目录&复制代码
      • 2.2 C文件转换为汇编文件
    • 三. 剖析汇编文件
    • 四. 指令相关
    • 五. 额外记录:指令段相关调用

一. 前提准备

  • Linux虚拟机

  • Gcc编译器(若采用Linux虚拟机剖析,则自带无需下载)

  • C语言的Hello World代码

    #include 
    
    int main(){
      printf("Hello World!");
      return 1;
    }
    

二. C转换为汇编操作准备

2.1 创建目录&复制代码

C语言的Hello World的汇编剖析(64位 Intel架构)_第1张图片

2.2 C文件转换为汇编文件

​ 若将C文件转换为汇编文件,则需要编译器作为桥梁,这里使用gcc编译器,由于为只需编译成汇编文件,所以采用—S这个选项命令即可

zhp@root:~$ gcc --help

....
-S     Compile only; do not assemble or link.
....

汇编文件如图所示

C语言的Hello World的汇编剖析(64位 Intel架构)_第2张图片

三. 剖析汇编文件

前提概要:

  • b:1字节,8bit
  • w:2字节,16bit
  • l:4字节,32bit
  • q:8字节,64bit

Hello World所经历的步骤剖析:

  1. 栈空间的开辟,使栈基址指向新空间基址,并让栈针sp定位道栈基址bp位置
  2. 并通过Hello World字符串地址值存放edi寄存器
  3. 调用printf函数打印Hello World
  4. 返回值保存寄存器中
  5. 还原bp
  6. 还原栈空间,sp还原

C语言的Hello World的汇编剖析(64位 Intel架构)_第3张图片

ps:查看输出Hello World

C语言的Hello World的汇编剖析(64位 Intel架构)_第4张图片

四. 指令相关

ret指令:

  1. 弹出返回地址值并保存到指令地址寄存器
  2. 通过可选项n,从栈中释放参数
  3. 恢复调用过程

下图截至intel手册Volume 3 6.4节
C语言的Hello World的汇编剖析(64位 Intel架构)_第5张图片

五. 额外记录:指令段相关调用

就如Hello World的输出

OS正在运行自身程序,突然来了C语言一段代码,调用它
C语言的Hello World的汇编剖析(64位 Intel架构)_第6张图片


详细步骤分析

  1. 指令段A首先需要调用call命令,来调用指令段B
  2. 这时需要先开辟栈空间等一系列操作,上方已经讲过,不在赘述
  3. 当调用后,需要返回到指令段A继续执行,这时需要用到ret指令
    C语言的Hello World的汇编剖析(64位 Intel架构)_第7张图片

指令段之间的调用,若有参数传递时,则会有2种方式

  1. 一种是存储到一个公共地方,即通用寄存器
  2. 另一种通过栈本身特性,为指令段A的数据开辟一段栈帧,指令段B通过bp的pop/其他方式,来获取数据

第二种方式的操作非常耗时,但也不是抛弃这个方式,由于寄存器数量有限(和计算机的位数相关,如你的计算机是32位,则有32个寄存器),当通用寄存器耗尽时,就可采用此方式。

⭐️更详细的指令间参数调用可参考:指令段间及文件间参数调用过程(64位 Intel架构)

你可能感兴趣的:(计算机学习,c语言,汇编,架构)