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

ARM 汇编 C语言 for循环


在使用 Keil 编译基于 STM32F103 的 C 语言程序时,生成的汇编代码会有一些不同。STM32F103 是基于 ARM Cortex-M3 内核的微控制器,因为汇编语言是 ARM 汇编,而不是 x86 汇编。

示例 C 代码
假设我们有如下的简单 C 语言 for 循环代码:

void loop_example(void) {for (int i = 0; i < 10; i++) {// loop body}
}

Keil 编译生成的 ARM 汇编代码
使用 Keil 编译器(如 ARMCC 或 ARMCLANG)编译上述代码,生成的汇编代码可能类似于以下内容。

loop_example PROC; Setup the stack frame (if required)PUSH    {lr}           ; Save the link register; Initialize i = 0MOVS    r1, #0         ; r1 = i = 0loop_start; Compare i with 10CMP     r1, #10        ; Compare i with 10BGE     loop_end       ; If i >= 10, jump to loop_end; Loop body; (Insert loop body code here); Increment iADDS    r1, r1, #1     ; i++; Jump back to start of loopB       loop_startloop_end; Clean up and returnPOP     {pc}           ; Restore the link register and returnENDP

解释

  1. 初始化:MOVS r1, #0 将寄存器 r1(用于变量 i)初始化为0。
  2. 条件判断:CMP r1, #10 将 r1 与10进行比较,BGE loop_end 如果 r1 大于或等于10,则跳转到 loop_end 结束循环。
  3. 循环体:在条件成立的情况下执行循环体代码(这里省略了具体的操作)。
  4. 增量:ADDS r1, r1, #1 增加 r1 的值,然后 B loop_start 跳回条件判断部分。
  5. 返回:POP {pc} 恢复链接寄存器并返回。

关于寄存器和指令

  • MOVS: 将一个立即数加载到寄存器,并设置条件代码。
  • CMP: 比较两个寄存器的值,并设置条件代码。
  • BGE: 条件分支指令,当比较结果为大于或等于时跳转。
  • ADDS: 将两个寄存器的值相加,并将结果存储到第一个寄存器,同时更新条件代码。
  • PUSH 和 POP: 用于保存和恢复寄存器的值,特别是链接寄存器 lr。

注意事项
实际生成的汇编代码可能会根据具体的编译器优化选项和编写的 C 代码有所不同。
使用 Keil 编译器时,可以通过查看生成的 .asm 文件来查看编译后的汇编代码。(关于如何配置keil生成asm汇编文件,详见配置keil生成asm汇编文件)

同时可以看下这篇文章汇编 for循环

相关文章:

  • 【设计模式深度剖析】【8】【行为型】【备忘录模式】| 以后悔药为例加深理解
  • 为什么说Python 是胶水语言?
  • C# OpenCvSharp 代数运算-add、scaleAdd、addWeighted、subtract、absdiff、multiply、divide
  • 大型企业IT基础架构和应用运维体系
  • 基于Java的诊所医院管理系统,springboot+html,MySQL数据库,用户+医生+管理员三种身份,完美运行,有一万一千字论文
  • 【DevOps】Logstash详解:高效日志管理与分析工具
  • macOS Sequoia 将 Mac 生产力与智能化提升至全新高度 (macOS 15 ISO、IPSW、PKG 下载)
  • 69. UE5 RPG 使用Gameplay Cue 实现技能表现效果
  • 9M高速USB转接芯片CH347转双串口转I2C转SPI转JTAG转SWD
  • Linux内核中的锁
  • 判断QT程序是否重复运行
  • Qt自定义日志输出
  • 【MySQL】索引(上)
  • 如何连接达梦数据库?
  • java框架技术xml文件存档
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • Objective-C 中关联引用的概念
  • React系列之 Redux 架构模式
  • VUE es6技巧写法(持续更新中~~~)
  • vue数据传递--我有特殊的实现技巧
  • 前端攻城师
  • 如何实现 font-size 的响应式
  • 使用 @font-face
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 你对linux中grep命令知道多少?
  • C# - 为值类型重定义相等性
  • gunicorn工作原理
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • PostgreSQL之连接数修改
  • ​​​【收录 Hello 算法】9.4 小结
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (3)llvm ir转换过程
  • (42)STM32——LCD显示屏实验笔记
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)计算机毕业设计ssm电影分享网站
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (七)Knockout 创建自定义绑定
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (三)SvelteKit教程:layout 文件
  • (数据结构)顺序表的定义
  • (循环依赖问题)学习spring的第九天
  • (转)ORM
  • (转)scrum常见工具列表
  • (转)平衡树
  • .Mobi域名介绍
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .net6+aspose.words导出word并转pdf
  • .NET6实现破解Modbus poll点表配置文件
  • .Net各种迷惑命名解释