条件码
多少位
ARM是32bit处理器,所以它的
字是32bit的。0x0000 0000
半字自然就是16bit;0x0000
字节不论在哪个CPU上都是8bit。0x00
NZCV
N 1为负 0为正
本位设置成当前指令执行结果的第31位。当两个由补码
表示的有符号整数运算时,N=1 表示结果为负数;否则结果
为正数或零
Z 1为零 0为非零
Z=1 表示运算的结果为零,否则结果不为零
C 加进1 减借0
分 4 种情况:
- 在加法指令中(包括比较指令CMN),当结果产生了进位,则C=1,表示无符号数运算发生上溢出,其它 情况下C=0
- 在减法指令中(包括比较指令CMP),当运算中发生了借位,则C=0,其它情况下C=1
- 对于在操作数中包含移位操作的运算指令(非加/减指令),C被设置成被移位寄存器最后移出去的位
- 对于其它非加/减法运算指令,C的值通常不受影响
V 溢出1
分两种情况:
- 对于加/减运算指令,当操作数和运算结果都是以二进制的补码表示的带符号的数时,且运算结果超出了有符号运算的范围时溢出。V=1 表示符号位溢出
- 对于非加/减法指令,通常不改变标志位 V 的值
指令
ARM 指令有几种寻址方式
ARM 指令有 8 种寻址方式。分别是:
立即数寻址、寄存器寻址、寄存器移位寻址、寄存器间接寻址、基址变址寻址、多寄存器寻址、堆栈寻址、相对寻址
LDM/STM
寻址方式 | 说明 | pop | =LDM | push | =STM |
---|---|---|---|---|---|
FA | 递增满 | LDMFA | LDMDA | STMFA | STMIB |
FD | 递减满 | LDMFD | LDMIA | STMFD | STMDB |
EA | 递增空 | LDMEA | LDMDB | STMEA | STMIA |
ED | 递减空 | LDMED | LDMIB | STMED | STMDA |
多寄存器
类型 | 每次基址寄存器操作 | 传送起始地址 | Rn序号变化 |
---|---|---|---|
IA | 先传数据,后基址加4 | (Rn) | + |
IB | 先基址加4,后传数据 | (Rn)+4 | + |
DA | 先传数据,后基址减4 | (Rn) | - |
DB | 先基址减4,后传数据 | (Rn)-4 | - |
无论如何高寄存器高地址 |
栈
类型 | 堆栈类型 | pop | push |
---|---|---|---|
FA | 递增满 | LDMFA | STMFA |
FD | 递减满 | LDMFD | STMFD |
EA | 递增空 | LDMEA | STMEA |
ED | 递减空 | LDMED | STMED |
常用现场保与恢复 |
- STMFD SP!,{R0 - R7,LR};现场保存,将R0~R7、LR入栈,SP值更新 。
- LDMFD SP!,{R0 - R7,PC}^;恢复现场,包括CPSR,异常处理返回,SP值更新。
^
后缀“^”说明
- 寄存器列表不包含PC:使用后缀“^”进行数据传送时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器。
- 寄存器列表包含有PC:除了正常的多寄存器传送外,还要将SPSR拷贝到CPSR中。该用法可用于异常处理返回。
- 禁用情况:后缀“^”不允许在用户模式或系统模式下使用。 因为它们没有SPSR
ARM是小端 高位高地址
ARM 体系结构支持 7 种运行模式
用户模式、系统模式、快速中断模式、一般中断模式、管理模式、终止模式、未定义模式
伪指令、宏指令
伪指令的作用
- 程序定位的作用;
- 为非指令代码进行定义;
- 为程序完整性做标注;
- 有条件的引导程序段。
声明全局变量伪指令
- GBLA 定义一个 全局数字变量,其默认初值为 0 ;GBLA Test1
- GBLL 定义一个 全局逻辑变量 ,其默认初值为 FALSE;GBLL Test2
- GBLS 定义一个 全局字符串变量,其默认初值为空 ;GBLS Test3
声明局部变量伪指令
定义一个ARM程序中的局部变量,并将其初始化。与全局变量同理
- LCLA
- LCLL
- LCLS
数据定义伪指令
- SETA伪指令用于给一个数字变量赋值;
- SETL伪指令用于给一个逻辑变量赋值;
- SETS伪指令用于给一个字符串变量赋值;
其他伪指令
- LTORG用于声明一个数据缓冲池(文字池)的开始。
- MAP^ FIELD# SPACE% DCB= DCD&
32位到16位指令
1 | 32 位编码 ; |
CPSR/SPSR
从高到低为FSXC
1 | MRS R0, CPSR |
异常与中断PC值
汇编语言程序段的基本结构
1 | Init, , ;只读的代码段名叫Init |
ARM与C混合编程
ATPCS
ATPCS规定,ARM的数据堆栈为FD型堆栈,即递减满堆栈。
还有对于参数个数不多于4的函数,编译器必须按参数在列表中的顺序,自左向右为它们分配寄存器R0~R3。
如果函数的参数多于4个,那么多余的参数则按自右向左的顺序压入数据堆栈,即参数入栈顺序与参数顺序相反。
C调用ARM
1 | tt, , |
LDR R1,[SP]
LDR R2,[SP,#4]
BX LR
extern void strcopy(char *d,const char * s);
1 | extern void strcopy(char *d,const char * s); |
ARM调用C
1 | int g(int a, int b, int c, int d, int e) |
STR LR, [SP,#-4]!
ADD SP, SP, #(4)
LDR PC, [SP],#4
1 | f |
混合编程
内联汇编
它不支持 Thumb 指令;除了程序状态寄存器 CPSR 之外,不能直接访问其他任何物理寄存器等;
如果在内联汇编程序指令中出现了以某个寄存器名称命名的操作数,那么它被叫做虚拟寄存器,而不是实际的物理寄存器。
1 | void enable_IRQ(void) |
1 | void Read_mode(void) |
嵌入式汇编
与内联汇编不同,嵌入式汇编具有真实汇编的所有特性,数据交换符合 ATPCS 标准,同时支持 ARM 和Thumb,所以它可以对目标处理器进行不受限制的低级访问。但是不能直接引用 C/C++ 的变量
1 | _ _asm int add(int i, int j) |
PWM
PWM 概念(脉宽调制)就是只对一方波序列信号的占空比按要求进行调制,而不是改变方波信号的其它参数,即不改变 幅度和周期,因此脉宽调制信号的产生和传输,都是数字式的。