cpu的工作模式 p41
cpu的寄存器 p43, 没有小黑三角的寄存器表示多个工作模式下共用的,
带有小黑三角的表示此模式下独有
arm cpu的寄存器r0-r12通用寄存器, 随便使用
PC寄存器装着要取指的下条指令的内存地址(取指-> 译码-> 执行)
cpsr: 当前程序状态寄存器, 记录当前工作模式,条件位状态等
spsr: 备份的程序状态寄存器, 用于保存cpsr的值
1. 在c里内嵌汇编
__asm__ __volatile__(
"汇编代码 \n"
"汇编代码 \n"
:"=r"(c变量名)
:"r"(c变量名)
:"r0", "r1"
);
2. (mov rd, #立即数或寄存器), 把立即数或寄存器的值给rd寄存器
3. ldr rd, =立即数, 立即数没限制,
4. add rd, r0, #立即数或寄存器 //r0+#立即数或另一寄存的值放入rd寄存器
5. sub rd, 被减数, 减数
6. mul rd, rm, rn
CPSR / SPSR (架构手册P49)
31 30 29 28 7 6 4--0
N Z C V I F M[4:0]
工作模式位(架构手册P52)
I bit: Disables IRQ interrupts when it is set.
F bit: Disables FIQ interrupts when it is set.
N bit: 表示指令里目标寄存器的结果为负数时, N=1, 如为正数或零时N=0
Z bit: 如指令运算的结果为0, 则Z=1, 如果结果不是0, 则Z=0
C bit: 如果指令运算的结果产生进位或借位时, C=1, 如果没有, C=0
V bit: 如果指令运算的结果溢出时, V=1, 如果没有V=0
因cpsr是个特殊的寄存器, 需用特定的汇编指令来读取出来
mrs r0, cpsr
默认情况下, 一般的指令都不会根据目标寄存器里的结果来改变cpsr里的值, 需要特定的汇编指令
才会改变cpsr的值
cmp
movs
adds
subs
...
7. condition flasg : N(负数) Z(是否零) C(进位/借位) V(溢出)
conditon: 架构手册/p112
eq(0000) : 当cpsr里的Z位的值为1时, 此条件成立, 否则条件不成立, 使用此条件的
汇编指令不会执行
ne(0001) : 当cpsr里的Z位的值为0时, 此条件成立, 使用此条件的汇编指令会执行
8. cmp Rn, #立即数/寄存器 //根据Rn减去第二个参数的值的结果更新cpsr的条件标志位
9. movs Rd, #5 //先把5放入Rd, 再根据Rd里的结果更新cpsr的条件标志位
10. 移位lsl, lsr 逻辑左移, 右移
"lsl r0, r0, #4 \n"
asr 算术右移(C语言里>>是算术右移)
11. and rd, rn, #立即数或者寄存器 //把两个数位与上后,把结果放入rd寄存器 add rd, #4 == add rd, rd, #4
orr rd, rn, #立即数或者寄存器 //把两个数位或上后,把结果放入rd寄存器
mvn r0, #4 //把4的反码存入r0寄存器
12. bic rd, rn, op(#立即数或寄存器) //清除rn对应op里的相应位是1的值(可指定多位), 把结果放入rd
13. ldr rd, [rn]
14. str r0, [rn]
注意: ldr/str的"[]"符号里不能写立即数的地址, 必须要把地址保存到寄存器后才可以操作
15. ldr/str 操作4个字节 ldrb/strb操作1个字节 ldrh/strh操作2个字节
在内嵌汇编里, 输入输出的%寄存器要用固定的寄存器来操作,尢其是输入的,一进去应用一个固定的寄存器代替它
16, ldr rd, [rm, rn/#立即数] //把rm寄存器上值加上rn值的结果作为地址,再把地址上值放入rd
17. mydata:
.word 0x789, 0x123
.word func
18 mystr:
.string "hello"
.align 2
r13寄存器就是sp寄存器, 用于记录当前栈顶所在的内存地址
19. stmfd sp!, {r0-r3}
ldmfd sp!, {r0-r3}