ARM学习笔记(⼀)汇编语⾔
汇编table指令什么意思
ARM学习笔记(⼀)汇编语⾔
你好!这是⾃动化专业“嵌⼊式系统设计”的课程总结笔记。参考书⽬:《嵌⼊式计算系统设计原理》《ARM7数据⼿册》
ARM 编程模型
编程模型是所有⽤户可见的寄存器的集合。
ARM寄存器简介
在ARM⽤户模式下,⽤户可见寄存器共有17个,包括r0-r15和程序状态寄存器CPSR。ARM寄存器字长和数据总线宽度⼀致,都是是32位的。
r0-r12:通⽤寄存器,保存变量
r13:栈顶指针寄存器
r14:连接寄存器。函数调⽤时,先将下⼀条指令的地址存⼊r14,再将r15置成⽬标函数的地址。函数返回时,将r14的值赋给r15。
如果遇到函数嵌套,每次嵌套调⽤都要将r14压栈,再将r15赋给r14。
r15:程序计数器(PC),指向下⼀条待取指令的地址。假设当前执⾏的指令在地址a处,因为ARM是三级流⽔线,所以PC指针实际指向的地址是(a+8)。ARM要求所有的指令(不考虑Thumb指令集)是32位宽的,并且起始地址32位对齐,即指令地址低两位是0。下图为ARM的三级流⽔线结构。
CPSR:当前程序状态寄存器,包括NZCV四个状态位和三个控制选项。
标志位功能
N负数标志位。运算结果ans为负,N=1; 否则 N=0
Z零标志位。ans=0,则Z=1;ans=1,Z=0
C进位标志位。加法运算,最⾼位有进位,则C=1,否则C=0;减法运算,最⾼位有借位,则C=0,否则C=1;移位运算,C保存移出的位。
V溢出标志位,结果溢出为1,否则为0
IF中断屏蔽标志位,分成 I 和 F 两位。分别负责 IRQ 和 FIQ 的屏蔽,被置1时屏蔽对应的中断
T T=1时使⽤Thumb指令集,T=0时使⽤ARM指令集
MODE选择当前处理器⼯作模式
关于ARM7的⼯作模式
好多关于ARM7的博⽂中都提到 ARM7 有 7 种⼯作模式。但是我到的ARM7的中⽂数据⼿册上只有六种,缺了系统模式
(SYS)。
USR:⽤户模式,程序正常运⾏时的模式
SYS:系统模式
IRQ:普通中断模式
FIQ:快速中断模式,有更⾼的优先级和响应速度。可以打断 IRQ 普通中断,并且在进⼊ FIQ 中断处理程序后会关闭 IRQ。
SVC:管理模式,即使⽤ SWI 指令进⼊的管态
ABT:中⽌模式,⾮法访问内存时进⼊的模式
UND:⽆定义模式,指访问的指令缺少类似协处理器的硬件⽀持,可以在该模式下进⾏协处理器的软件仿真
上述 7 种模式中,USR 以外的统称特权模式;USR 和 SYS 以外的统称异常模式。
汇编指令
ARM 指令集可以划分为若⼲⼦类,每类指令具有相同的编码⽅式,下⾯介绍三类常见指令。
数据处理指令
数据处理指令的编码格式如下图:
该指令编码的注解如下:
条件代码:ARM 的所有数据处理指令都⽀持条件执⾏。⽐如 ADDNE,表⽰在 CPSR 中的 Z 标志位等于 0 时执⾏该加法指令。这⾥的 “NE” 将被编码成 4 位的条件代码。
I:指⽰第⼆操作数是⽴即数(1)还是寄存器(0)
操作码:数据处理指令共 16 个,使⽤ 4 位⼆进制编码
S:指⽰当前操作是否修改CPSR,S=1 则修改。
RN:第⼀操作数
RD:⽬的寄存器
操作数:第⼆操作数
指令介绍
下图是 ARM7 中⽂数据⼿册中关于数据处理指令的描述。其中SBC和RSC写错了,改为:
SBC - Rd := Op1 - Op2 -1 + C
RSC - Rd := Op2 - Op1 -1 + C
ps1:TEQ 命令描述中的 EOR 是异或运算。
ps2:BIC 命令的作⽤是按位清 0,到 Op2 中的 1 所在的位,把Op1中相应的位清 0。(Bit Clear)
补充知识点① ARM寻址⽅式
这部分内容参考了博主 的⽂章,想要详细了解可以移步
ARM 指令集都是32位宽的,同时地址总线也是32位,所以在汇编指令⾥⽆法直接指定内存的绝对地址(进不去,怎么想都塞不进去吧,何况好多指令都是三操作数),想要访问内存就必须借助⼀些技巧。
但是寄存器只有16个,只需4位就可以寻址,所以寄存器寻址还是可以的。
这⼀点和MU0处理器有所不同,MU0是单操作数指令,加上地址空间很⼩,所以所有内存单元都是直接指定内存的绝对地址。
ARM 的寻址⽅式共有⼋种。
⽴即数寻址:符合某种特定条件的⽴即数可以直接作为操作数,仅限第⼆操作数。例如,MOV R0,#&38; MOV R0,#0x6400;ps:所有⽴即数前⾯要有#;0x 和 & 都代表 16 进制。寄存器直接寻址:ADD R0,R1,R2
寄存器间接寻址:ARM 处理器是 Load-Store 结构,所有数据运算的操作数都是寄存器。要想操作内存,必须先把内存数据加载到寄存器。所以这种寻址⽅式只会出现在 LDR,STR 等数据传送指令中。例如,LDR R0,[R1]
寄存器偏移寻址:个⼈认为这不算⼀种寻址⽅式,它只是在寄存器直接寻址的基础上对取出的操作数增加了移位操作。例如,MOV R0,R2,LSL #3; R2的值左移3位,结果赋给R0。
寄存器基址变址寻址:分为三类:
① 前变址:LDR r0, [r1, #4] ; r0 = mem[r0 + 4]
② 前变址,⾃动变址:STR r0, [r1, #4]! ; r1 = r1 + 4, r0 = mem[r1]③ 后变址,⾃动变址:LDR r0, [r1], #4 ; r0 = mem[r1], r1 = r1 + 4相对寻址:在B、BL等控制流指令中⽤到。常见格式:BL init 。详见控制流指令章节。堆栈寻址
多寄存器寻址
在以上寻址⽅式中,寄存器间接寻址、基址变址寻址、堆栈寻址(堆栈也是内存)、多寄存器寻址、块拷贝寻址都涉及内存操作,只能⽤于数据传送指令(存疑,操作数在内存上的命令只能是Load-Store命令吗?欢迎评论区指出)。详见【数据传送指令】章节。
补充知识点 ② 关于第⼆操作数
ARM 的数据处理指令是三操作数指令。( 按照ARM7⼿册的分类,MUL/MLA不属于数据处理指令,它是根据编码格式分类的 )分别是⽬的操作数、第⼀操作数、第⼆操作数。其中⽬的操作数和第⼀操作数使⽤ 4 位⼆进制编址,因此只能使⽤只有16种地址选择的寄存器直接寻址。第⼆操作数的变址空间有12位,因此它的使⽤更加灵活。在数据处理指令中,还可以使⽤寄存器偏移寻址和⽴即数寻址。
寄存器偏移寻址
如前所述,寄存器偏移寻址是对第⼆操作数的移位。所以第⼆操作数的 12 位要指明三件事:
① 操作数所在的寄存器(4位)
② 移位⽅式 (四种:逻辑左或右, 算术右或循环右、2位)
③ 移位次数 (0-31、5位)
共需要11位,所以可以在单个指令编码中塞下。具体实现见下图。
ARM7⼿册种还给出了另⼀种编码⽅式,感兴趣的朋友可以参阅
⽴即数寻址
这部分内容强烈推荐的博⽂:
ARM的数据总线有 32 位,但是留给第⼆操作数的空间只有 12 位。所以⽴即数的范围必须有所限制。在这 12 位中,0 ~ 7位是数值部分;8~11 位乘以 2 是 0~7 位要进⾏右移位操作的次数。因此,⽴即数的表⽰范围是:(0 - 255)* 2 。
⼀个判断⽴即数是否合法的简便⽅法:将它写成⼆进制,观察是否能通过右移偶数次,使得所有的 “1” 都位于低⼋位上。
数据传送指令2N

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。