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

嵌入式之汇编程序示例

目录

经典例子:求阶乘

一:数组求和

二:数据压栈退栈

三:函数嵌套调用  


经典例子:求阶乘

 知识点:

  • 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

相关文章:

  • GATT 服务的核心函数bt_gatt_discover的介绍
  • DataGrip安装文档
  • 面向超大规模模型的提示词工程
  • 网络安全从零开始(一):基础技能全解析
  • 【数据结构初阶】顺序表专题
  • TypeScript入门到精通
  • 零基础学习计算机网络编程----网络基本知识
  • 为什么尺规无法三等分任意角?
  • C++中IO类(iostream、fstream和sstream)知识详解和应用
  • IPython 常用魔法命令
  • 安全语音通信系统python
  • AGI大模型(33):LangChain之Memory
  • python炸鱼船
  • 【成品论文】2025年电工杯数学建模竞赛B题50页保奖成品论文+matlab/python代码+数据集等(后续会更新)
  • 第十七次CCF-CSP算法(含C++源码)
  • Linux10正式版发布,拥抱AI了!
  • Python性能优化利器:__slots__的深度解析与避坑指南
  • 分布式锁总结
  • MSP430G2553 USCI模块串口通信
  • 【疑难杂症】Vue前端下载文件无法打开 已解决
  • 制作网站首页教案/查淘宝关键词排名软件有哪些
  • 怎么创建个网站/it培训机构哪家好
  • 全国网站制作公司/今日热点新闻视频
  • 招聘网站建设技术要求/搜索引擎外部链接优化
  • 企业局域网组建与网站建设/seo运营做什么
  • 滁州网络推广公司/杭州网站优化公司