空指令--nop
nop
传输指令--MOV
MOV R1,#3 @用c表示 r1=3;
MOV R1,#0X17 @r1=0x17;
MOV R0,R1 @ r0 =r1;
MVN R0,R1 @将RO取反给R1 相当于r1 = ~r0;
建议赋值时候直接给16进制方便调试
算术指令集 --加法ADD 减法SUB 乘法MUL
ADD R0,R1,R2 @R0 = R1+R2
SUB R0,R1,#3 @R0 =R1 - 3
MUL R1,R2,R3 @R1 =R2*R3
ADD R0,#1 @R0 = R0+1
@ADD不会进位
@ADDS 带进位的加法,进位时反映但CPSR的C位
@ADDC 带进位的加法、加运算时,加上CPSR的C位
移位指令--左移LSL,右移LSR
MOV R0,R1,LSL#2 @R0 = R1<<2
MOV R2,R1,LSR#1 @R2 = R1>>1
ADD R2,R0,LSR#1 @R2 = R2+R0>>1
@lsl逻辑移位
@asl算数移位
@关于算数移位和逻辑移位的知识:@https://blog.youkuaiyun.com/cg2258911936/article/details/103574604
MOV R0,R1,LSL#2 @R0=R1<<2;
MOV R2,R1,LSR#1 @R2=R1>>1
ADD R2,R0 LSL#1 @R2 = R2+R0<<1
@CPSR访问指令
跳转指令--B,BL
B label @跳转到label标签
B main @跳转到标号为main的代码处
BL func @保存下一条要执行的指令的位置到LR寄存器,跳转函数func
@当跳转代码结束后,用MOV,PC,LR返回
CPSR访问指令MRS ,MSR
MRS R0 ,CPSR @R0 = CPSR;
MSR CPSR,R0 @CPSR = R0;
位运算AND ORR BIC TST
AND R0,R1,#0XFF @R0 = R1&0XFF
ORR R3,R0,#0X0F @R3 = R0|0X0F
BIC R0,R0,#0X03 @清除R0中的0号位和1号位
TST R0,#0X20 @测试第5位是否为0,为0则Z标志置1
比较指令--CMP
CMP R0,R1
@比较RO与R1的值
@注意:比较结果反映在CPSR中的N Z C位
@R0>R1 Z = 1
@R0<R1 C = 1
@R0=R1 Z = C = 1
条件指令执行实例
一系列指令都使用条件指令
if (a == 0) x = 1;
CMP R1,#0
MOVEQ R0,#1
置标志位,再使用不同的条件码
if (a == 0) x = 0;
if (a > 0) x = 1;
CMP R0,#0
MOVEQ R0,#0 @EQ是等于
MOVGT R1,#1 @GT是大于
使用条件比较指令
if (a == 4 || a == 10) x = 0;
CMP R0,#4
CMPNE R0,#10
MOVEQ R1,#0
状态码
int r0=1;
int r1=5;
int r2=3;
int max;
max=(r0>=r1)?r0:r1;
max=(max>=r2)?max:r2;
练习
@测试当前工作状态是否为ARM,是的话 R5 = 0XFF
MRS R0,CPSR
TST R0,#0X20
MOVEQ R5,#0XFF
@修改当前工作模式,切换到User模式
MRS R0,CPSR
BIC R0,#0X1F
ORR R0,#0X10
MSR CPSR,R0
Load/Store指令
注意:LOAD/STORE架构规定,存储器之间不能直接拷贝,需通过寄存器做中转
LDR R0,[R1] @R0 = *R1 R1里面存放的是地址,把该地址存放的内容读入到R0中
@LDRB(BYTE)读1字节 LDRH(HALF WORD)读2字节 LDR 读4字节
STR R0,[R1] @*R1 =R0 将寄存器R0中值写入存储器地址为R1的空间中
堆栈寻址LDMFD/STMFD
堆栈寻址是一种数据结构;按照先进后出的方式存储数据R13(SP)
寄存器指示当前栈顶位置,ARM处理器支持4中堆栈操作方式(FD,FA,ED,EA,)
ATPCS标准规定使用FD栈
LDMFD SP!,{R0-R12}@入栈,地址走向-》由高到低
STMFD SP!,{R0-R12}@出栈,地址走向-》由低到高
例如:
STMFD SP!,{R0-R12,LR} 将寄存器R0~R12 LR中的值存入栈中
@常用于中断保护现场
LDMFD SP!,{R0-R12,PC}^ 将栈中值逐个弹出到寄存器R0~R12 PC中(LR恢复pc@常用于中断恢复现场,^表示会恢复SPSR到CPSR
基址变址寻址
基址变址寻址:就是将基地址寄存器的内容与指令中给出的偏移量相加,得到一个有效的操作数的地址,通常用于访问连续的地址空间
三种索引方式:
前索引 LDR R0, {R1, #4}
自动索引 LDR R0, {R1, #4}! R1 = R1+4
后索引 LDR R0, {R1},#4
软中断指令SWI
SWI 0X02 产生软中断,软中断号为2
GNU伪指令
.text @将定义符开始的代码编译到代码段
.data @将定义夫开始的代码编译到数据段
.end @文件结束
.global 符号 @将符号声明为全局符号;
.byte @单字节定义 .byte 0x12,'a',23
.long/.word @定义4字节数据 .word 0x12345678