基础学习
寄存器和基本指令学习
| 寄存器 | 用途 |
|---|---|
| R0 | 工作寄存器 |
| R1 | |
| R2 | |
| R3 | |
| R4 | 必须保护 |
| R5 | |
| R6 | |
| R7 | |
| R8 | |
| R9 | |
| R10 | |
| R11 | fp |
| R12 | ip |
| R13 | sp |
| R14 | lr |
| R15 | pc |
| CPSR | 标志寄存器 |
MOV指令:移动,赋值
mov r0,#100 r0=100;
mov r0,r1 r0=r1;
常数以#开头,默认10进制,16进制加前缀0x
ADD指令:相加
add r0,r1,r2 r0=r1+r2;
add r0,r0,#5 r0=r0+5;
add r1,r1,r1 r1=r1+r1;
SUB指令:相减
sub r0,r1,r2 r0=r1-r2;
sub r0,r1,#5 r0=r1-5;
sub r1,r1,r1 r1=r1-r1 r1=0;
寻址方式:
立即寻址/寄存器寻址/寄存器移位寻址
移位指令:LSL/LSR/ASR/ROR/RRX
LSL:逻辑左移<<
MOV r0,r1,LSL #2 r0=r1*2^2 即r0=r1*4 常用于数组寻址
LDR指令:读/加载
LDR用于从储存器(内存)加载数据到寄存器。
LDR{type}{cond} Rd,label{!}
LDRD{cond} Rd,Rd2,label{!} (一次加载双字(64位))
{!} 是否将寻址结果写入寄存器中
type 取值:
B 无符号字节
SB 有符号字节
H 无符号半字
SH 有符号半字
label为内存地址
STR指令:写入
寄存器间接寻址: ADD R0,R1,[R2] ;R0←R1+[R2]
LDR R0,[R1] ;R0←[R1] r0=*r1 中括号相当于指针
基址变址寻址:
基址变址寻址就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址:
LDR R0,[R1,#4] ;R0←[R1+4] 即R0=*(R1+4)
LDR R0,[R1,#4]! ;R0←[R1+4]、R1←R1+4
LDR R0,[R1] ,#4 ;R0←[R1]、R1←R1+4
LDR R0,[R1,R2] ;R0←[R1+R2]
LDM指令:
LDM指令是批量从内存加载数据到寄存器列表
LDM{addr_mode}{cond} Rn{!} reglist
addr_mode类型。用于数据的存储和读取有一下几种情况:
IA 每次传送后地址值加
IB 每次传送前地址值加
DA 每次传送后地址值减
DB 每次传送前地址值减
对于堆栈操作有如下几种情况:
FD 满递减堆栈
ED 空递减堆栈
FA 满递增堆栈
EA 满递增堆栈
stmfd sp!, {fp, lr}
ldmfd sp!, {fp, pc}
堆栈寻址:
一般用于保存子程序现场。
STM与LDM成对出现
STMFD SP!,{R1-R7,LR}
… 函数代码
LDMFD SP!,{R1-R7,LR}
stmfd sp!, {fp, lr}
….. 函数代码
ldmfd sp!, {fp, pc}
跳转指令:
B 指令
跳转指令也称为分支指令,它可以改变CPU的执行流程。
ARM中有两种方式可实现跳转
- 1、修改PC寄存器
- 2、使用跳转指令
B指令格式: b{cond} label
BL 指令
带链接跳转,会将下条指令的地址保存到LR寄存器,并跳转到目标地址。
bl{cond} label
一般用于子程序(函数)调用。在子程序尾部可以用 MOV PC,LR来返回上层调用。
BX 指令
带状态切换的跳转指令
格式: BX{cond} Rm
当满足{cond}条件时,处理器会检查Rm[0]是否为1,如果Rm[0]=1,则处理器自动将CPSR的T标志位置位,并将目标代码解释为Thumb指令集;
如果Rm[0] = 1,处理器将T标志位复位,并将目标代码解释为 ARM指令集
实例: .code 32 ADR R0,thumb1+1 BX R0 .code 16 thumb1:
BLX指令
BX 与 BL的结合体!
指令条件码 {cond} 表示条件码
| 助记符 | 标志 | 含义 |
|---|---|---|
| EQ | Z=1 | 相等 |
| NE | Z=0 | 不相等 |
| GE | N=V | 有符号数大于或等于 |
| LT | N!=V | 有符号数小于 |
| LE | Z=1 , N!=V | 有符号数小于或等于 |
| GT | Z=0,N!=V | 有符号数大于 |
跳转指令举例:
bne label
bge label
ble label
CMP指令:
cmp{cond} Rn,operand2
CMP指令将Rn寄存器的值减去operand2的值,并设置标志寄存器。相当于subs Rn,operand2
e.g. cmp r0,0 判断r0的值是否为0