ARM汇编学习笔记 Day02

1. 什么是立即数?怎么判断合法立即数

立即数就是直接写在指令里面的常数,前面带个#,数值直接编码在指令内部,不用去内存拿数据。 比如mov r0,#0x10,这里#0x10就是立即数。

这里很容易踩坑,ARM32的指令固定占32位,除去操作码、寄存器编号,留给立即数的位置不多。 合法立即数要求:

  1. 如果某个数的数值范围是0~0xFF之间,那么这个数一定是立即数;
  2. 把某个数展开成2进制,这个数的最高位1至最低位1之间的二进制数序列的位数不能超过8位;
  3. 这个数的二进制序列凑够8位之后的的右边必须为偶数个连续的 0

举个例子,#0xFF是没问题的;但像#0x104,拼不出来,就是非法立即数。 碰到非法立即数,就不能直接写#,得用LDR伪指令去加载。

2. ldr 和 str 是干啥的

CPU的通用寄存器不能直接访问内存,读写内存全靠这两条。

ldr:把内存的数据读到寄存器。

复制代码
ldr r0, [r1]

r1里面存内存地址,把这个地址上的数据拿出来放到r0。

⚠️注意区分,还有一个ldr r0,=0x12345678,这个不是真正的内存访问指令,是伪指令,专门用来加载那些非法立即数。

str:反过来,把寄存器的数据写到内存里面。

复制代码
str r0, [r1]

把r0的值,存进r1指向的内存地址。

简单记:ldr读,str写。

3. orr、bic指令

平时操作寄存器某几位的时候经常用。

orr,按位或,用来把某些bit置1。

复制代码
orr r0, r0, #0x08

掩码哪一位是1,寄存器对应的bit就变成1,其他位不动。

bic,位清零,把指定bit清成0。

复制代码
bic r0, r0, #0x08

掩码里面哪一位是1,就把寄存器对应bit清零,其余保持原样。

实操记一句:orr置1,bic清0。配置外设寄存器的时候用得巨多。

4. stmfd 和 ldmfd

ARM默认用满递减栈,这两条就是栈的入栈、出栈,批量操作多个寄存器。

stmfd sp!, {r0,r1,lr} 相当于入栈,把r0、r1、lr这些寄存器的值压到栈上保存现场,sp往低地址挪。

ldmfd sp!, {r0,r1,lr} 出栈,把栈上的数据拿回来,恢复到寄存器,sp往高地址走。

那个!千万不能丢!不加的话sp不会更新,栈直接乱掉,程序跑飞。

5. b、bl、bx三者区别

都是跳转,但用途差别很大。

b:单纯跳转,跳过去就完事,不会保存返回地址,跳走之后回不来。

复制代码
b loop

bl:函数调用用的。跳转之前,会把下一条指令地址存到lr(r14)寄存器。函数执行完靠lr回到原来的地方。

复制代码
bl func

bx:跳转到寄存器存的地址,还能切换ARM、Thumb指令集。我们写代码最常见就是bx lr,做函数返回。

总结:

  • b:随便跳,不保存返回地址
  • bl:调用函数,存返回地址到lr
  • bx:按寄存器地址跳转,用来返回,切换指令集

6. mrs、msr

CPSR这个状态寄存器比较特殊,普通mov指令不能直接读写。

mrs:读。把cpsr的值读到通用寄存器。

复制代码
mrs r0, cpsr

msr:写。把通用寄存器的值写回cpsr。

复制代码
msr cpsr, r0

比如切换处理器模式,流程就是先用mrs读cpsr到r0,修改r0里面对应的bit,再msr写回cpsr。 有个坑:用户模式下改不了CPSR模式位,得在特权模式才可以改。

7. ARM栈一共几种?实际用哪种

一共4种,看sp指向哪、栈往哪个方向增长:

  1. FD 满递减栈:sp指向已经存好的有效数据;入栈sp向低地址减小
  2. FA 满递增栈:sp指向有效数据;入栈sp向高地址变大
  3. ED 空递减栈:sp指向下一个还没存东西的空位;入栈往低地址
  4. EA 空递增栈:sp指向下一个空位;入栈往高地址

名词简单理解: 满栈:sp指向的位置有有效数据;空栈:sp指向的地方是空的。 增栈:入栈往高地址;减栈:入栈往低地址。

我们裸机开发默认用 FD满递减栈

简单复盘

今天这些都是常考的基础点,过一遍:

  1. 立即数是指令内部的常量,ARM有严格的编码约束,拼不出来就用LDR伪指令;
  2. ldr读内存,str写内存;
  3. orr置位,bic清零;
  4. stmfd入栈保存现场,ldmfd出栈恢复,!不能漏;
  5. b直接跳转,bl做函数调用存lr,bx用来返回;
  6. mrs读cpsr,msr写cpsr;
  7. 4种栈,裸机默认满递减栈FD。
相关推荐
xx~t2 小时前
嵌入式——ARM——汇编1
linux·汇编·arm开发·嵌入式硬件·arm
ouynagda2 小时前
嵌入式与ARM内核基础体系梳理
arm开发
学linux的QQ蛋2 小时前
零基础吃透ARM体系架构与底层原理
arm
PiaoKe___3 小时前
从端云解耦到可编程 Android 实例:云手机架构解析与 Python 批量管控实战
arm开发·python·架构·自动化
H_oRIZoN_3 小时前
Linux入门DAY44 ARM 入门 Day02|ARM 汇编指令、模式切换、栈操作、汇编 C 混合编程
linux·单片机·嵌入式硬件·arm·linux应用编程
Horn Still Sounds13 小时前
ARM嵌入式基础|内核、寄存器、架构、存储、汇编移位全面梳理
arm开发·单片机·嵌入式硬件·硬件架构
susplus13 小时前
【初识ARM】ARM相关基础概念
学习·arm
myy-learn15 小时前
ARM-知识扫盲1
arm
从零开始的嵌入式之旅15 小时前
day44
arm开发·经验分享·笔记·嵌入式硬件