目录
LDM:(load much)多数据加载,将地址上的值加载到寄存器上
STM:(store much)多数据存储,将寄存器的值存到地址上
mov(move)
MOV
从另一个寄存器、被移位的寄存器、或一个立即值装载一个值到目的寄存器。
mov r0,r1 ---> 把r1的值赋给r0
mov r0,#立即数 --->r0=立即数,如mov r0,#0x0010
例如:
MOV AX,2000H;将16位数据2000H传送到AX寄存器
MOV AL,20H;将8位数据20H传送到AL寄存器
MOV AX,BX;将BX寄存器的16位数据传送到AX寄存器
MOV AL,[2000H];将2000H单元的内容传送到AL寄存器
ldr:读内存
LDR指令用于从内存中将一个32位的字读取到指令中的目标寄存器中,如果目标寄存器为PC,则可以实现“长”跳转。主要有一下3种方式使用:
LDR R0,[R1]; 将存储器地址为R1的字数据读入寄存器R0。
LDR R0,[R1,#8];将存储器地址为R1+8的字数据读入寄存器R0。
LDR R0,=0xff ; 这里的LDR不是arm指令,而是伪指令。这个时候与MOVE很相似,只不过MOV指令后的立即数是有限制的。这个立即数必须是0X00-OXFF范围内的数经过偶数次右移得到的数,所以MOV用起来比较麻烦,因为有些数不那么容易看出来是否合法,此处等同mov R0,#0xff(如果数目很大则不能等同,如ldr r0, =0x56000056,在裸机中,=后的数会先保存在sdram中,然后才运行语句,如果没有初始化sdram使用该语句会出错,代码重定位前=后的数要注意是否超过OXFF)。
ldr r0,=_start; 同上,这里面出现的“=”预示着这是一条伪指令,这个是取得标号_start的“绝对地址”,这个绝对地址就是在link的时候确定的,就是编译地址。
ldr r0,_start; 从内存地址_start的地方,把其对应的 命令执行对应的 “执行码”读入到r0中。
如 :
_start: .
word OS_CPU_IRQ_ISR
ldr pc,_start; 这个含义类似于ldr r0,_start,不同的是 读取执行码直接到 pc中,这样就实现了直接跳转到_start运行了。重定位后需要跳转到sdram中使用该指令_start可换成C函数的函数命,如跳转到main()函数,ldr PC,=main
LDRB
LDRB 的指令格式与LDR相似,只不过它是将存储器地址中的8位(1个字节)读到目的寄存器中。
LDRH的指令格式也与LDR相似,它是将内存中的16位(半字)读到目的寄存器中。
STR写内存命令
str r0,[r1] 把r0的值,写到r1寄存器的地址上,覆盖r1上的值
STR R0,[R1,#8] 将R0中的字数据写入以R1+8为地址的存储器中。
例子
B : 分支
B{条件} <地址>
B 是最简单的分支。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的地址,从那里继续执行。
死循环
BL : 带连接的分支
bl用于子程序跳转,要返回地址,返回地址存于LR中。当发生bl跳转前,会在寄存器 R14 (即LR)中保存当前PC-4,即bl跳转指令的下一条指令的地址。所以在返回时只要 MOV pc,lr 。
该跳转指令是位置无关码,在反汇编中跳转地址为基地址+offset,与ldr r0,=_start不同。在重定位之前使用该跳转,如跳转到内存初始化的c函数sdram_init(),bl sdram_init
CMP(比较)指令:比较整数
cmp r1, r2 /* r1==r2?
若执行指令后:ZF=1,则说明两个数相等,因为zero为1说明结果为0.
汇编条件判断 eq neq
cpsr[30]是zero位,主要保存最近的一次“是否相等”的条件判断的结果
zero位状态由cmp 指令来设置
除cmp之外,运算操作都可以通过加上s后缀来设置修改zero位结果
几乎所有的指令(除了cmp和加了s后缀的指令:说白了就是修改zero位的指令后不能再加eq和neq)都可以加上eq或neq的后缀来读取zero位状态,并根据zero位状态来决定是否执行该指令
eq == equal 相等,即zero位保存的条件判断结果是相等时,本指令执行,否则不执行
ne == notequal 不相等,即zero位保存的条件判断结果不相等时,本指令执行,否则不执行
LDM:(load much)多数据加载,将地址上的值加载到寄存器上
STM:(store much)多数据存储,将寄存器的值存到地址上
汇编指令:LDM、STM详解_xld123-CSDN博客_ldm指令
1.高标号存高地址
2.注意“!”,有!的话,寄存器最后的地址要更改,没有则不变