arm的汇编指令:
arm的最后一个操作数可以是:
寄存器、立即数、寄存移位操作
数据处理指令:
传输指令、
MOV{S}<c> <Rd>, #<const>
MOV{S}<c> <Rd>, <Rm>
************************************************
mov 传输指令、
{S} movs 表示可以根据运算结果更改cpsr的nzcv
<c> 表示指令可以条件执行(movlt)
<Rd> 目标寄存器
<Rm> 操作数
#<const> 立即数(直接操作数)
************************************************
立即数:8位的数值循环右移或循环左移偶数位形成数值
0x1880
00 0000 0000 0000 0000 0000 00 01 1000 10
0x811
0000 0000 0000 0000 0000 1000 0001 0001
0x001f8
判断数字是否为立即数:
1.将数值转换位32位二进制
2.循环移位偶数位将1尽量移动到最右端,使两个相邻1之间0最少
3.去掉左边偶数个0,看剩余数值是否为0位以内
取反传输:
mvn r0, #0x0 ==== r0 = (~0x0)
mvn r0, r1 ==== r0 = ~r1
MOV (shifted register) 表示操作数可以进行移位操作
lsr 逻辑右移 低位消失,高位补0
lsl 逻辑左移 高位消失,低位补0
ror 循环右移 低位移动到高位的操作
asr 算数右移 符号位保留,移位操作按照逻辑右移进行,空位补符号位
MOV{S} <Rd>, <Rm>, ASR #<n>
ASR{S} <Rd>, <Rm>, #<n>
MOV{S} <Rd>, <Rm>, LSL #<n> ==== Rd = (Rm<<n)
LSL{S} <Rd>, <Rm>, #<n> ==== Rd = (Rm<<n)
MOV{S} <Rd>, <Rm>, LSR #<n> ==== Rd = (Rm>>n)
LSR{S} <Rd>, <Rm>, #<n> ==== Rd = (Rm>>n)
MOV{S} <Rd>, <Rm>, ROR #<n>
ROR{S} <Rd>, <Rm>, #<n>
MOV{S} <Rd>, <Rm>, ASR <Rs>
ASR{S} <Rd>, <Rm>, <Rs>
MOV{S} <Rd>, <Rm>, LSL <Rs> ==== Rd = (Rm<<Rs)
LSL{S} <Rd>, <Rm>, <Rs> ==== Rd = (Rm<<Rs)
MOV{S} <Rd>, <Rm>, LSR <Rs> ==== Rd = (Rm>>Rs)
LSR{S} <Rd>, <Rm>, <Rs> ==== Rd = (Rm>>Rs)
MOV{S} <Rd>, <Rm>, ROR <Rs>
ROR{S} <Rd>, <Rm>, <Rs>
指令有两个操作时,第一操作数必须是寄存器,第二操作数可以是立即数,寄存器,寄存器移位操作
运算指令
add 加法:
add r0, r1, #3 ==== r0 = r1+3
add r0, r1, r2 ==== r0 = r1+r2
add r0, r1, r2, lsr #3 ==== r0 = r1+(r2>>3)
sub 减法:第一操作数减第二操作数
sub r0, r1, #12 ==== r0 = r1-12
rsb 第二操作数减第一操作数
rsb r0, r1, #12 ==== r0 = 12-r1
mul 乘法
mul r0, r1, r2 ==== r0 = r1*r2
64位数据加减法运算:
adc 带进位的加法
adc r0, r1, #12 ==== r0 = r1+12+C(进位标志位)
sbc 带借位的减法
sbc r0, r1, #12 ==== r0 = r1-12-!C
位操作指令
and 按位与,清零操作 &
and r0, r1, #12 ==== r0 = r1&12
orr 按位或,置1操作 |
orr r0, r1, r2 ==== r0 = r1 | r2
eor 按位异或 ^
eor r0, r1, #12 ==== r0 = r1 ^ 12
bic 位清除 清除第一操作数中第二操作数为1的那些位置
bic r0, r1, #1<<13 ==== r0 = r1 &(~(1<<13))
**************************************************
条件码:
eq 测试相等执行代码
ne 测试不相等执行代码
lt 小于执行代码
le 小于等于执行代码
gt 大于执行代码
ge 大于等于执行代码
**************************************************
比较指令 ;无条件更改NZCV标志,不保存结果
cmp CMP<c> <Rn>, #<const>
cmp r0, r1 ==== cpu根据r0-r1 的结果更改cpsr寄存器的NZCV
cmp r0, #12 ==== cpu根据r0-12 的结果更改cpsr寄存器的NZCV
cmn 取反比较
cmn r0, r1 ==== cpu根据r0+r1 的结果更改cpsr寄存器的NZCV
teq 测试相等 , 可以使用的条件ne ,eq
teq r0, r1 ==== cpu根据r0^r1 的结果更改cpsr寄存器的NZCV
tst 位测试指令,判断第一操作数,第二操作为1的那些位是0还是1
可以使用的条件ne( 需要测试的位为1) , eq(需要测试的位为0)
tst r0, r1 ==== cpu根据r0&r1 的结果更改cpsr寄存器的NZCV
标号:地址的助记符,没有空间只代表地址
在keil环境
顶格的字母组合(同函数命名规则)
在gnu环境:
标号定义
fun:
跳转指令(分支指令)
相对跳转:基于当前pc前后32M范围内寻找标号
b fun //不带返回的跳转,跳转到fun处执行代码
bl fun //带返回跳转
绝对跳转:
mov pc, #12
arm的伪指令:编译工具会自动将伪指令编程位几条arm指令
ldr pc, =0x12345678
ldr pc, =fun
arm的伪指令:编译工具会自动将伪指令编程位几条arm指令
ldr r0, =0x12345678 //将任意32位数写入 r0=0x12345678
ldr r0, =fun //将fun标号表示的地址写入r0
adr r0, fun //在1024范围内寻址fun
nop
特殊寄存器操作指令
msr cpsr ,r0 === cpsr = r0
mrs r0, cpsr === r0 = cpsr
内存操作指令
单寄存器
ldr/str 完成一个字(4个字节)交互
ldr r0, [r1] ==== r0=*r1
str r0, [r1] ==== *r1=r0
前索引:先地址查找,后内存操作,基地址不改变
ldr r0, [r1, #4] ==== r0 = *(r1+4)
ldr r0, [r1, r2] ==== r0 = *(r1+r2)
str r0, [r1, #4] ==== *(r1+4) = r0
后索引:先内存操作,后地址修改(基地址修改)
ldr r0, [r1], #4 ==== r0=*r1,r1=r1+4
str r0, [r1], #4 ==== *r1=r0,r1=r1+4
str r0, [r1], r2 ==== *r1=r0,r1=r1+r2
基址变址:先地址查找,后内存操作,基地址改变
ldr r0, [r1, #4]! ==== r0 = *(r1+4),r1=r1+4
str r0, [r1, #4]! ==== *(r1+4) = r0,r1=r1+4
ldrb/strb //完成8位数据操作
ldrh/strh //完成16位数据操作
ldr/str //完成32位数据操作
ldrd/strd //完成64位数据操作
多寄存器操做遵守的规则:小编号寄存器对应低地址空间
多寄存器操作
ldm ;加载连续内从空间数据到多个指定寄存器(单位按字)
stm ;保存多个指定寄存器内容到连续内存空间
ldm r0, {r1,r2,r3} === r1=*r0 r2=*(r0+4) r3=*(r0+8) r0=r0
stm r0, {r1,r2,r3} === *r0=r1 *(r0+4)=r2 *(r0+8)=r3 r0=r0
ldm r0, {r1,r2,r3}! === r1=*r0 r2=*(r0+4) r3=*(r0+8) r0=r0+8
stm r0, {r1,r2,r3}! === *r0=r1 *(r0+4)=r2 *(r0+8)=r3 r0=r0+8
ldmia/stmia(ldm/stm) 先内存操作后地址+4
ldmib/stmib 先地址+4后内存操作
ldmdb/stmdb 先地址-4后内存操作
ldmda/stmda 先内存操作后地址-4
栈操作指令
ldmfd/stmfd 满减栈(arm默认),sp指向的空间不能直接使用,需要先地址-4,后内存操作
ldmfa/stmfa 满增栈
ldmed/stmed 空减栈
ldmea/stmea 空增栈
入栈:stmfd sp!, {r0-r12}
出栈:ldmfd sp!, {r0-r12}^ ^表示模式恢复
push {r1,r2};入栈
pop {r1,r2};出栈
特殊寄存器操作指令
cpsr 的操作指令
mrs r0, cpsr ==== r0=cpsr
msr cpsr, r0 ==== 写cpsr=r0
模式修改:
异常发生cpu会自动修改
在特权模式使用指令修改
协处理器操作指令
协处理,协助主处理器进行电路管理的处理器
arm有16个协处理
cp15协处理,cp15协处理有16个32位寄存器,c0-c15