{ }{s} , 解释:
:指令码 {
}:条件码 {s}:状态位,如果在指令后面加上s,则运算的结果会影响CPSR的条件位
:目标寄存器
:第一操作数,可以是寄存器,也可以是立即数 按照指令码将第一操作数运算后的结果保存在目标寄存器 指令码功能:
mov:将第一操作数的值保存在目标寄存器
mvn:将第一操作数的值按位取反,将结果保存在目标寄存器
格式:
{ }{s} , , 解释:将第一操作寄存器的数值移位第二操作数指定的位数,将结果保存在目标寄存器中
指令码:
LSL:左移运算 低位补0
LSR:右移运算 高位补0
ROR:循环右移:低位移出的值补到高位
格式:
{ }{s} , , 解释:将第一操作寄存器和第二操作数进行位运算,将结果保存在目标寄存器中
指令码:
and:与 与0清0 与1不变
orr:或 或1置1 或0不变
eor:异或 相同为0 不同为1
bic:按位清零指令,想将哪一位设置为0,只需要用bic指令给这一位运算一个1即可
格式:
{ }{s} , , 解释:将第一操作寄存器的值和第二操作数进行算数运算,结果保存在目标寄存器中
add:加法运算
adc:进行加法运算时需要考虑CPSR的条件位
sub:减法运算
sbc:进行减法运算时需要考虑CPSR的条件位
mul:乘法运算
格式: cmp 第一操作数,第二操作寄存器
比较两个数据
cmp命令本质:实际上就是比较的两个数进行减法运算,并且减法运算的结果会影响到CPSR寄存器的条件位
通常比较指令完毕之后会使用条件码进行判断,根据判断的结果做不同的逻辑
{ } 标签 功能:跳转到指定的标签下
指令码:
b:跳转时不影响LR寄存器的值
指令码{条件码} 目标寄存器 [目标地址]
str 目标寄存器 ,[目标地址]:将目标寄存器的数据写入到以目标地址为起始的内存中
ldr 目标寄存器 ,[目标地址]:从以目标地址为起始的内存中读一个字的数据到目标寄存器
向内存中写:
str:向内存中写一个字(4字节)的数据
strh:向内存写半个字(2字节)的数据
strb:向内存写一个字节的数据
从内存读:
ldr:从内存读取一个字的数据
ldrh:从内存读取半个字的数据
ldrb:从内存读取一个字节的数据
向内存写:
stm 目标地址,{寄存器列表}
将寄存器列表中每一个寄存器的值都写道目标地址指向的连续空间之中
从内存读
ldm 目标地址,{寄存器列表}
将目标地址指向的连续内存中的数据读到寄存器列表中的寄存器中
注意事项:
1.如果寄存器列表中寄存器的编号连续,可以用-表示列表,如果不连续,用,分割寄存器
{r1-r5,r7}
2.无论寄存器列表中如何表示,我们在读写内存的时候始终是低地址 对应低寄存器编号
增栈:压栈结束后,栈顶往地址大的方向增长
减栈:压栈结束后,栈顶往地址小的方向增长
空栈:压栈结束后,栈顶区域没有有效数据
满栈:压栈结束后,栈顶区域存放有效数据
空增栈(EA)/空减栈(ED)/满增栈(FA)/满减栈(FD)
ARM使用的栈是满减栈
.text
.global _start
_start:
ldr sp,=0X40000020 @初始化栈
b main
main:
mov r1,#1
mov r2,#2
bl func
add r3,r1,r2
b main
func:
@压栈保护现场
stmfd sp!,{r1,r2}
mov r1,#3
mov r2,#4
sub r4,r2,r1
@出栈恢复现场
ldmfd sp!,{r1,r2}
mov pc,lr @返回main函数
wh:
b wh
.end
.text
.global _start
_start:
ldr sp,=0X40000020 @初始化栈
b main
main:
mov r1,#1
mov r2,#2
bl func
add r3,r1,r2
b main
func:
@压栈保护现场
stmfd sp!,{r1,r2,lr}
mov r1,#3
mov r2,#4
bl fun1
sub r4,r2,r1
@出栈恢复现场
ldmfd sp!,{r1,r2,lr}
mov pc,lr @返回main函数
fun1:
@压栈保护现场
stmfd sp!,{r1,r2}
mov r1,#4
mov r2,#5
mul r5,r1,r2
@出栈恢复现场
ldmfd sp!,{r1,r2}
mov pc,lr
wh:
b wh
.end