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

Linux学习-ARM汇编指令

一、移位指令

  • 逻辑左移(LSL)MOV <Rd>, <Rm>, LSL #<n>,功能是逻辑左移,低位补0。
  • 算术右移(ASR)MOV <Rd>, <Rm>, ASR #<n>,功能是算术右移,符号位保持不变。

二、 什么是立即数?如何判断某数是不是一个12位立即数?

  • 立即数:指在指令中直接包含的常数,无需从内存或寄存器读取。例如 MOV R0, #0x123 中的 0x123 就是立即数。
  • 12位立即数判断:判断一个数是否为合法的12位立即数,需满足以下三点:
  1. 数值范围在 0~0xFF(8位立即数)。
  2. 将该数展开为二进制后,从最高位1到最低位1之间的二进制数序列的位数不超过8位。
  3. 该数二进制最低位1后的0的个数为偶数。

三、加载指令

  • LDR伪操作(加载非立即数)Ldr <Rd>, =非立即数
  • LDR内存加载LDR <cc> <Rd>, [<Rn>], #+/- <im12>,用于从内存中加载数据,支持条件执行(<cc>)和自动索引。
位操作指令
  • ** bic(位清除)**:功能是指定位清零。
  • ** orr(位设置)**:功能是指定位置1。

四、b.blbx 指令的区别

  • b/bl

    • 用于相对跳转(基于当前PC值计算偏移),只能跳转到当前指令前后±32MB范围内。
    • b 是单纯跳转;bl 跳转前会将返回地址存入 lr(链接寄存器),用于函数调用。
    • 不改变处理器状态(ARM/Thumb模式不变)。
  • bx

    • 用于绝对跳转(目标地址来自寄存器,如 bx r0),可跳转到任意地址。
    • 跳转时会根据目标地址的最低位(0:ARM模式,1:Thumb模式)切换处理器状态。
    • 不自动保存返回地址,需手动处理(如 mov lr, pc; bx r0)。

五、条件标志位(CPSR寄存器的N、Z、C、V位)

汇编指令加S后缀时,执行过程会更新CPSR寄存器的这四个标志位:

  • N(负标志位):在结果是有符号二进制补码的情况下,结果为负数则N=1,非负数则N=0
  • Z(零标志位):结果为0则Z=1,非零则Z=0
  • C(进位/借位标志位)
    • 无符号数最高有效位向更高位进位时,C=1
    • 减法中运算结果的最高有效位从更高位借位时,C=0
  • V(溢出标志位)
    • 有符号数中,两个最高有效位均为0的数相加,结果最高有效位为1;或两个最高有效位均为1的数相加,结果最高有效位为0时,V=1
    • 其余情况V=0

六、跳转与函数调用

  • 无条件跳转(b)b label,直接跳转到label处执行。
    示例:
    b label
    mov r0, #3   ; 跳转会跳过该指令
    mov r1, #5
    label:
    mov r2, #4
    
  • 函数调用(bl)bl 函数名,跳转的同时将返回地址保存到lr寄存器,用于函数返回。
  • 循环实现(类似while(1))
    finished:
    b finished
    

七、栈操作(STMDB/STMFD、LDMIA/LDMFD)

  • 入栈(STMDB/STMFD):将寄存器列表中的值压入栈中,STMFDSTMDB的别名(满递减栈)。
    示例:stmfd sp!, {r0 - r8} ,将r0r8的寄存器值压入栈,sp自动递减。
  • 出栈(LDMIA/LDMFD):从栈中弹出值到寄存器列表,LDMFDLDMIA的别名(满递减栈)。
四种栈类型的区别

栈的类型由栈指针(SP)指向的位置入栈/出栈时SP的变化方向决定:

  • 满栈(Full):SP指向最后一个已入栈的数据(非空)。
  • 空栈(Empty):SP指向即将入栈的空位置(栈顶无数据)。
  • 增栈(Ascending):入栈时SP增大(向高地址生长)。
  • 减栈(Descending):入栈时SP减小(向低地址生长)。

具体分类:

  1. 满减栈(Full Descending, FD):SP指向最后入栈的数据,入栈时SP减小(STMFD SP!, {R0-R3})。
  2. 满增栈(Full Ascending, FA):SP指向最后入栈的数据,入栈时SP增大。
  3. 空减栈(Empty Descending, ED):SP指向空位置,入栈时SP减小。
  4. 空增栈(Empty Ascending, EA):SP指向空位置,入栈时SP增大。
ARM内核使用的栈类型

ARM默认推荐使用满减栈(FD),这是ARM架构中最常用的栈类型。例如:

  • 函数调用时通过 STMFD SP!, {R0-R3, LR} 保存寄存器,LDMFD SP!, {R0-R3, PC} 恢复现场。
  • 操作系统(如Linux)和多数编译器均默认采用FD栈。

八、ARM汇编与C函数调用的规则(ATPCS标准)

为确保调用兼容性,需遵循ARM-Thumb Procedure Call Standard (ATPCS)

(1)汇编调用C函数
  1. 参数传递:前4个参数用 R0-R3 传递,超过4个的参数入栈(满减栈,参数从右向左入栈)。
  2. 返回值:32位返回值存 R0,64位存 R0-R1
  3. 寄存器保护
    • 调用者保存:R0-R3R12(IP)、LR(返回地址)。
    • 被调用者(C函数)保存:R4-R11SP(栈指针)。
  4. 调用步骤
    ; 传递参数(前4个用R0-R3)
    MOV R0, #1    ; 第一个参数
    MOV R1, #2    ; 第二个参数
    ; 调用C函数(自动保存LR)
    BL c_function 
    ; 结果在R0中
    
(2)C调用汇编函数
  1. 函数声明:C中声明汇编函数为 extern,如 extern int asm_func(int a, int b);
  2. 汇编函数实现
    • EXPORT 导出函数名(如 EXPORT asm_func)。
    • 遵循参数传递规则(从 R0-R3 取参数)。
    • 保护 R4-R11(若使用需入栈保存,退出前恢复)。
    • BX LR 返回(或 MOV PC, LR,需确保模式正确)。
  3. 示例
    EXPORT asm_func
    asm_func:; R0 = a, R1 = bADD R0, R0, R1  ; 计算a+b,结果存R0BX LR           ; 返回
    

九、特殊寄存器操作(MRS、MSR)

  • MRS(读取特殊寄存器):格式为MRS <cc> <Rd>, <spe_reg>,用于将特殊寄存器(如CPSR)的值读取到通用寄存器。
    示例:MRS r0, cpsr ,将CPSR的值读到r0
  • MSR(写入特殊寄存器):格式为MSR <cc> <spe_reg>, <Rd>,用于将通用寄存器的值写入特殊寄存器。
    示例:MSR cpsr, r0 ,将r0的值写入CPSR。
  • 模式切换示例(以User模式为例)
    mrs r0, cpsr    ; 读取CPSR到r0
    bic r0, r0, #0x1F  ; 清除模式位
    orr r0, r0, #0x10  ; 设置为User模式
    msr cpsr, r0    ; 写入CPSR完成模式切换
    ; 若在Keil中上述指令报错,可改用:msr cpsr_c, r0
    

文章转载自:

http://CIi70Zej.dkgtr.cn
http://IYFhMpl3.dkgtr.cn
http://BvFjnkij.dkgtr.cn
http://oBrNjfId.dkgtr.cn
http://9hACTvri.dkgtr.cn
http://RrShbtJ2.dkgtr.cn
http://o65dJiMp.dkgtr.cn
http://rRWU9QJj.dkgtr.cn
http://o3VGHGaY.dkgtr.cn
http://XQheCWFW.dkgtr.cn
http://kk5CyABE.dkgtr.cn
http://3CjC4euR.dkgtr.cn
http://GsBjsrVX.dkgtr.cn
http://wv5OCAJL.dkgtr.cn
http://j5dSjT63.dkgtr.cn
http://phJQHKgB.dkgtr.cn
http://XeQkCfWd.dkgtr.cn
http://zrr8PRrJ.dkgtr.cn
http://jIIXimVW.dkgtr.cn
http://imRkXu6C.dkgtr.cn
http://rts1VGFN.dkgtr.cn
http://UK2SXm9c.dkgtr.cn
http://dOxdBO2i.dkgtr.cn
http://JzcEiTQF.dkgtr.cn
http://IOfxeA9o.dkgtr.cn
http://qCGOq0bN.dkgtr.cn
http://oX4qyZIJ.dkgtr.cn
http://q4x3mKqS.dkgtr.cn
http://WKN8Ztue.dkgtr.cn
http://BPv49fjt.dkgtr.cn
http://www.dtcms.com/a/375627.html

相关文章:

  • 微软依旧稳定发挥,Windows 最新更新性能「开倒车」
  • 预录车辆号牌提示系统——车牌检测系统
  • --控制--
  • 明远智睿 H618 核心板:以硬核性能重塑多媒体智能终端新生态
  • FANUC发那科焊接机器人铝材焊接节气
  • 在python中使用mysql的方法
  • DriftingBlues: 4靶场渗透
  • Java基本数据类型
  • Ackley函数:优化算法领域的复杂试金石
  • ubuntu升级失败报错
  • 大数据存储域——Kafka实战经验总结
  • Games101 第五讲 Z-buffer
  • AI批量剪辑软件推荐使用运营大管家-AI短视频剪辑软件,剪辑效果好,过原创视频
  • 服装采购跟单系统的高效管理实践
  • OpenCSG 哈投达成战略合作,加速东北企业AI转型
  • Unity预设保存检测
  • Word2Vec词嵌入技术和动态词嵌入技术
  • CCRC IT产品安全检测认证体系是什么?
  • Nginx 实战系列(七)—— Nginx一键安装脚本详解
  • [数据结构——lesson5.1链表的应用]
  • ARM汇编 启动代码
  • ctfshow - web入门 - JAVA
  • 无法加载 DLL“xxxxxxx.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。
  • 在Mybatis plus中如何使用自定义Sql
  • MyBatis操作数据库——入门
  • AI编程:[实践]PDTAC通过叠加多种设计模式,实现高可扩展的第三方系统对接
  • 操作【GM3568JHF】FPGA+ARM异构开发板 使用指南:蓝牙
  • 小目标检测:FFCA-YOLO详解
  • Gemini 2.5 Flash Image Preview API:获取API Key、调用教程与深度技术解析
  • iOS 使用记录和能耗监控实战,如何查看电池电量消耗、App 使用时长与性能数据(uni-app 开发调试必备指南)