当前位置: 首页 > news >正文

C语言函数是如何变成汇编的

为了说明C语言如何被编译成汇编语言,我们可以通过一个简单的C程序,并使用ARM编译器来生成相应的汇编代码。

// simple.c
int add(int a, int b) {return a + b;
}int main() {int result = add(5, 3);return result;
}

使用ARM编译器生成汇编代码

我们使用 arm-none-eabi-gcc(GNU ARM Embedded Toolchain)来编译这个C程序并生成汇编代码。以下是在Linux或类似Unix系统上的操作步骤:

  1. 安装ARM编译工具链: 如果未安装,可以通过以下命令安装:

    sudo apt-get install gcc-arm-none-eabi

  2. 编译生成汇编代码: 使用 -S 选项来生成汇编代码。

    arm-none-eabi-gcc -S simple.c -o simple.s

  3. 查看生成的汇编代码: 打开生成的 simple.s 文件。

生成的汇编代码(simple.s)

	.cpu arm7tdmi.eabi_attribute 20, 1.eabi_attribute 21, 1.eabi_attribute 23, 3.eabi_attribute 24, 1.eabi_attribute 25, 1.eabi_attribute 26, 1.eabi_attribute 30, 6.eabi_attribute 34, 0.eabi_attribute 18, 4.file	"simple.c".text.align	2.global	add.arch armv4t.syntax unified.arm.fpu softvfp.type	add, %function
add:@ Function supports interworking.@ args = 0, pretend = 0, frame = 8@ frame_needed = 1, uses_anonymous_args = 0@ link register save eliminated.str	fp, [sp, #-4]!add	fp, sp, #0sub	sp, sp, #12str	r0, [fp, #-8]str	r1, [fp, #-12]ldr	r2, [fp, #-8]ldr	r3, [fp, #-12]add	r3, r2, r3mov	r0, r3add	sp, fp, #0@ sp neededldr	fp, [sp], #4bx	lr.size	add, .-add.align	2.global	main.syntax unified.arm.fpu softvfp.type	main, %function
main:@ Function supports interworking.@ args = 0, pretend = 0, frame = 8@ frame_needed = 1, uses_anonymous_args = 0push	{fp, lr}add	fp, sp, #4sub	sp, sp, #8mov	r1, #3mov	r0, #5bl	addstr	r0, [fp, #-8]ldr	r3, [fp, #-8]mov	r0, r3sub	sp, fp, #4@ sp neededpop	{fp, lr}bx	lr.size	main, .-main.ident	"GCC: (GNU Arm Embedded Toolchain 9-2020-q2-update) 9.3.1 20200408 (release)"

代码分析

add 函数
  • str fp, [sp, #-4]!:将当前帧指针 fp 的值保存到栈中,并将栈指针 sp 向下偏移4字节。! 表示更新后 sp 的值。
  • add fp, sp, #0:将 sp 的值赋给 fp,即建立当前函数的栈帧。
  • sub sp, sp, #12:为局部变量分配12字节的空间。
  • str r0, [fp, #-8]str r1, [fp, #-12]:分别将函数参数 ab 存储到栈帧中。
  • ldr r2, [fp, #-8]ldr r3, [fp, #-12]:从栈帧中加载参数 ab 的值到寄存器 r2r3
  • add r3, r2, r3:计算 a + b,结果存储在 r3 中。
  • mov r0, r3:将计算结果 r3 设置为函数返回值。
  • add sp, fp, #0:恢复栈指针 sp 到函数调用前的位置。
  • ldr fp, [sp], #4:恢复帧指针 fp 的值。
  • bx lr:返回到调用该函数的地方。lr 寄存器保存了返回地址。
main 函数
  • push {fp, lr}:将当前的帧指针 fp 和链接寄存器 lr 保存到栈中。
  • add fp, sp, #4:建立当前函数的栈帧。
  • sub sp, sp, #8:为局部变量分配8字节的空间。
  • mov r1, #3mov r0, #5:将常数 35 分别加载到寄存器 r1r0 中,作为 add 函数的参数。
  • bl add:调用 add 函数。
  • str r0, [fp, #-8]:将 add 函数的返回值存储到栈帧中。
  • ldr r3, [fp, #-8]:从栈帧中加载 add 函数返回值到寄存器 r3
  • mov r0, r3:将 r3 设置为 main 函数的返回值。
  • sub sp, fp, #4:恢复栈指针 sp 到函数调用前的位置。
  • pop {fp, lr}:恢复帧指针 fp 和链接寄存器 lr 的值。
  • bx lr:返回到调用该函数的地方。

总结

通过上述步骤,我们展示了如何使用ARM编译器将一个简单的C程序编译成汇编代码。这个过程包括安装编译工具链、编写和编译C代码、生成和分析汇编代码。生成的汇编代码展示了C程序如何在低级别实现,包括函数调用、参数传递和返回值处理等细节。

相关文章:

  • 基于AT32_Work_Bench配置AT32工程
  • RocketMQ快速入门:集成spring, springboot实现各类消息消费(七)附带源码
  • 热门开源项目
  • 【python】PyQt5初体验,窗口等组件开发技巧,面向对象方式开发流程实战
  • 报错:ZeroDivisionError_ division by zero
  • PHP框架之ThinkPHP框架
  • vscode插件开发之 - TestController
  • VUE3版本新特性
  • 05. Java多线程 join 方法
  • c++设计模式之一创建型模式
  • 1964springboot VUE 智慧社区可视化平台系统开发mysql数据库web结构java编程计算机网页源码maven项目
  • 问题解决:Problem exceeding maximum token in azure openai (with java)
  • 分布式光纤测温DTS使用的单模光纤与多模光纤有何区别?
  • Leetcode - 周赛401
  • 八大经典排序算法
  • 【刷算法】求1+2+3+...+n
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Java,console输出实时的转向GUI textbox
  • js正则,这点儿就够用了
  • Map集合、散列表、红黑树介绍
  • nginx 负载服务器优化
  • PHP 7 修改了什么呢 -- 2
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 前端_面试
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 事件委托的小应用
  • 写代码的正确姿势
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 带你开发类似Pokemon Go的AR游戏
  • 组复制官方翻译九、Group Replication Technical Details
  • ​如何防止网络攻击?
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • # Redis 入门到精通(一)数据类型(4)
  • #Linux(make工具和makefile文件以及makefile语法)
  • (10)ATF MMU转换表
  • (Java入门)学生管理系统
  • (笔试题)分解质因式
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET 直连SAP HANA数据库
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .NET导入Excel数据
  • .sdf和.msp文件读取
  • .so文件(linux系统)
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • ::什么意思