嵌入式之汇编程序示例

目录

经典例子:求阶乘

一:数组求和

二:数据压栈退栈

三:函数嵌套调用  


经典例子:求阶乘

 知识点:

  • BGT 用于判断 r2 > r0,确保循环执行 恰好 r0 次
  • BNE 用于判断 r2 ≠ r0,会导致循环多执行一次,得到错误结果。

这就是阶乘代码中必须使用 BGT 而非 BNE 的原因。

AREA Factorial, CODE, READONLYENTRYstartLDR sp, =0x40001000      ; 初始化栈指针MOV r0, #10              ; 设置输入值为10MOV r1, #1               ; 结果初始化为1MOV r2, #1               ; 循环计数器初始化为1loopCMP r2, r0               ; 比较计数器与输入值BGT end_loop             ; 如果计数器 > 输入值,结束循环MUL r1, r1, r2           ; 累乘:result *= counterADD r2, r2, #1           ; 计数器加1B loop                   ; 继续循环end_loopMOV r0, r1               ; 将结果存入r0
stopB stop                   ; 程序终止END

一:数组求和

例:编写一个ARM汇编程序累加一个“数组”的所有元素,碰上0时停止。结果放入 r4。

    area test, code, readonly  ; 定义代码段test,属性为代码段、只读entry                  ; 程序入口标记
startldr r0,=array          ; 将array的绝对地址加载到r0(正确写法应为ldr r0, =array)
loopldr r1,[r0],#4         ; 从r0地址读取数据到r1,然后r0自增4字节(4字节=字长,适用于32位数据)cmp r1,#0              ; 比较r1是否为0addne r4,r4,r1         ; 若r1≠0,将r1累加到r4(注意:r4未初始化,默认值不确定)bne loop               ; 若r1≠0,跳转回loop继续遍历
stopb stop                 ; 无限循环,程序在此处结束#DCD伪操作数据缓冲池技术#dcd机器码
arraydcd 0x11               ; 定义数组元素,0x11(十进制17)dcd 0x22               ; 0x22(十进制34)dcd 0                  ; 0(数组结束标记)

二:数据压栈退栈

例:先将栈地址设置为将要压栈的数据存入寄存器r1-r5中,然后压栈

AREA first, CODE, READONLYCODE32ENTRYstartLDR sp, =0x40001000      ; 初始化栈指针,指向0x40001000地址; 数据准备:设置寄存器初始值MOV r1, #0x11            ; r1 = 0x11MOV r2, #0x22            ; r2 = 0x22MOV r3, #0x33            ; r3 = 0x33MOV r5, #0x55            ; r5 = 0x55 (修正中文逗号为英文逗号); 压栈操作:保存寄存器值到栈STMFD sp!, {r1-r3, r5}   ; 保存r1-r3和r5到栈,SP自动递减; 数据清零:验证后续恢复操作MOV r1, #0               ; 清零r1MOV r2, #0               ; 清零r2MOV r3, #0               ; 清零r3MOV r5, #0               ; 清零r5; 出栈操作:从栈恢复寄存器值LDMFD sp!, {r1-r3, r5}   ; 从栈恢复r1-r3和r5,SP自动递增stopB stop                   ; 无限循环结束程序END

三:函数嵌套调用  

当有多级函数嵌套,函数返回值我们不可能都存储在通用寄存器中,必须利用ldm将程序跳转前的寄存器值以及函数的返回地址压栈。

AREA test, CODE, READONLYENTRYstartLDR sp, =0x40002000      ; 初始化栈指针MOV r1, #0x11            ; 设置r1 = 0x11MOV r2, #0x22            ; 设置r2 = 0x22MOV r3, #0x33            ; 修正中文逗号为英文逗号MOV r5, #0x55            ; 修正中文逗号为英文逗号BL child_func            ; 调用子函数ADD r0, r1, r2           ; 计算r0 = r1 + r2
stopB stop                   ; 无限循环结束程序; 非叶子函数(调用其他函数的函数)
child_funcSTMFD sp!, {r1-r3, r5, lr} ; 保存寄存器和返回地址到栈MOV r1, #10                ; 修改r1的值BL child_funcl             ; 调用子子函数LDMFD sp!, {r1-r3, r5, lr} ; 恢复寄存器和返回地址MOV pc, lr                 ; 返回主函数; 叶子函数(不调用其他函数的函数)
child_funclSTMFD sp!, {r1-r3, r5}     ; 保存寄存器到栈MOV r1, #11                ; 修改r1的值LDMFD sp!, {r1-r3, r5}     ; 恢复寄存器MOV pc, lr                 ; 返回父函数END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81093.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】第九弹——索引(下)

文章目录 🌏索引(上)回顾🌏使用索引🪐自动创建索引🪐手动创建索引🚀主键索引🚀普通索引🚀唯一索引🚀复合索引 🪐查看索引🪐删除索引🚀删除主键索引…

毕业论文格式(Word)

目录 Word目录怎么自动生成?快速生成试试这3个方法! - 知乎https://zhuanlan.zhihu.com/p/692056836目录生成需要先设置标题样式,这个不仅是目录生成需要,和后续的图表也有关系。 最好不要自己创建新的样式,而是在现有…

PostGIS实现栅格数据转二进制应用实践【ST_AsBinary】

ST_AsBinary解析与应用实践(同ST_AsWKB) 一、函数概述二、核心参数解析三、典型用法示例四、Out-DB 波段处理机制五、二进制格式与其他格式的转换六、性能与存储优化七、应用场景八、注意事项九、扩展应用:基于Python Web的栅格二进制数据的…

线性回归原理推导与应用(七):逻辑回归原理与公式推导

逻辑回归是一种分类算法,常用于二分类,也就是得出的结果为是和不是,例如通过各种因素判断一个人是否生病,信用卡是否违约等。逻辑回归在社会和自然科学中应用非常广泛, 前置知识 线性回归 逻辑回归的底层方法就是线…

Fastrace:Rust 中分布式追踪的现代化方案

原文链接:Fastrace: A Modern Approach to Distributed Tracing in Rust | FastLabs / Blog 摘要 在微服务架构中,分布式追踪对于理解应用程序的行为至关重要。虽然 tokio-rs/tracing 在 Rust 中被广泛使用,但它存在一些显著的挑战&#xf…

水果系列数据集- 葡萄grapes>> DataBall

该数据集可以用于目标检测,水果分类 ,文生图相关项目。 以下是图片样例:

HTTP协议接口三种测试方法之-postman

HTTP协议作为现代Web开发的基石,其接口测试是开发过程中不可或缺的环节。Postman作为最流行的API测试工具之一,能够极大提升我们的测试效率。本文将详细介绍如何使用Postman进行HTTP接口测试。 一、HTTP协议基础回顾 在开始使用Postman之前&#xff0c…

佰力博科技与您探讨半导体电阻测试常用的一些方法

一、两探针法​ 两探针法是一种较为基础的测试方法。该方法将两根探针与半导体样品表面紧密接触,通过电源在两根探针之间施加电压,同时使用电流表测量通过样品的电流,再根据欧姆定律计算电阻。​这种方法的优点在于操作简单、设备要求较低&a…

机器学习的一些基本概念

看了b站一个清华博士的视频做的笔记,对于人工智能的底层原理,训练方式,以及生成式文本输出,图片生成的底层原理有了一个了解,算是一个还不错的科普文。之前一直想要了解一下机器学习的入门原理,神经网络相关…

Python爬虫实战:研究Grab 框架相关技术

1. 引言 1.1 研究背景与意义 随着互联网的快速发展,网络上的数据量呈爆炸式增长。如何高效地获取和利用这些数据成为了当前的研究热点。网络爬虫作为一种自动获取网页内容的技术,能够按照一定的规则,自动地抓取万维网信息,在搜索引擎、数据挖掘、信息整合等领域有着广泛的…

uniapp 嵌入鸿蒙原生组件 具体步骤

关于怎么使用uniapp 嵌入鸿蒙原生组件 HBuilder X 版本 4.64 app-harmony文件下新建 index.uts button.ets button.ets里面复制uniapp 官方提供的 示例代码 https://uniapp.dcloud.net.cn/tutorial/harmony/native-component.html button.ets import { NativeEmbedBuilderO…

阿里云 OS Copilot 使用指南

安装: AlibabaCloudLinux: sudo yum install -y os-copilotUbuntu: curl -#S https://mirrors.aliyun.com/os-copilot/os-copilot-all-in-one-latest.sh | bash添加RAM用户 打开 https://ram.console.aliyun.com/users 复制AccessKey,Ac…

枚举类扩充处理

问题背景 由于 Java 不允许枚举继承另一个枚举(enum cannot extend enum),但可以通过 组合方式 或 工具类 来实现类似功能。 ✅ 解决方案一:组合方式引入原始枚举值 示例代码: public enum CustomErrorCodeEnum imp…

Spring Security探索与应用

Spring Security核心概念 框架定位与核心能力 Spring Security是Spring生态中实现应用级安全的核心框架,其官方定义为"强大且高度可定制的认证与访问控制框架"。作为Spring应用程序安全防护的事实标准解决方案,它通过模块化设计提供以下核心能力: 认证(Authenti…

蓝桥杯国14 不完整的算式

!!!!!!!!!!!!!!!理清思路 然后一步步写 问题描述 小蓝在黑板上写了一个形如 AopBC 的算式&#x…

扫描电镜:打开微观世界的“超维相机“

当你用手机拍摄一朵花的微距照片时,放大100倍已足够惊艳。但如果告诉你,科学家手中的"相机"能将物体放大百万倍,连病毒表面的蛋白突触都清晰可见,你是否会好奇这背后的黑科技?这把打开微观宇宙的钥匙&#x…

JVM学习(四)--对象内存布局

目录 一、对象内存布局 1、对象的实例化 1.1、你有几种方式创建对象? 1.2、创建对象的步骤 1.2.1、从字节码角度看待对象创建过程 1.2.2、从执行步骤角度分析 2、对象的内存布局 2.1、对象头 2.2、实例数据 2.3、对齐填充 3、对象的访问定位 3.1、句柄访…

SQL每日一题(4)

前言:第四更 虽然已经全部做完了,这套卷子非常推荐! 根据题目还原出来的原始表 employees表 idnameagestatus1张三28在岗2李四35在岗3王五42在岗4赵六NULL在岗5钱七58在岗6孙八24在岗7周九31离职8吴十-5在岗9郑十一45在岗10王十二52在岗 题…

如何做好一份技术文档?

文章目录 前言一、技术文档的核心原则二、技术文档的类型与场景三、技术文档的写作流程3.1 需求分析阶段(文档生产的基础)3.2 架构设计阶段(文档的骨架搭建)3.3 内容开发阶段(血肉填充)3.4 质量保障阶段&am…

怎么判断一个Android APP使用了KMM这个跨端框架

要判断一个 Android 应用是否使用了 KMM(Kotlin Multiplatform Mobile) 框架,可以通过以下方法逐步验证: 一、安装包结构分析 解压 APK 将 .apk 文件重命名为 .zip 并解压,检查以下特征: • kotlin/ 目录&a…