一、在内存中声明大数
name DCD v1, v2, vn
name EQU expression
{name} FILL N
DCD可直接在内存中声明带数据或常量或空词的单词,然后加载到寄存器中。每一个整数都存储在一个单独的词中。
name称为符号。
N必须是4的倍数。(例如,N=16,16 bytes = 4 words)
如果符号使用DCD或FILL创建,则值已分配内存地址。如果使用EQU创建,则该值只是一个普通常数。
如何得到一个符号的地址?
ADR Rd,label
二、从内存中加载和向内存存储
加载:
使用地址将数据加载到寄存器中
LDR{type} {cond} Rt, [Rn {, #offset}]
LDR{type} {cond} Rt, [Rn, #offset]!
LDR{type} {cond} Rt, [Rn], #offset
LDRB Rt, [rn, #offset]
Rt为用于加载的寄存器
Rn是内存地址所基于的寄存器
#offset为相对于Rn地址的偏移量
{type} 可以是B(存储一个字节)或省略(存储一个单词)
ldrb清除整个寄存器然后从内存中加载值到寄存器中
存储:
将Rt中的内容存储到主存中
STR{type} {cond} Rt, [Rn {, #offset}]
STR{type} {cond} Rt, [Rn, #offset]!
STR{type} {cond} Rt, [Rn], #offset
STRB Rt, [Rn, #offset]
strb将寄存器中最低位的字节写入目标内存字节
第一个为有即时偏移量的加载和存储
第二个为带有预索引即时偏移量的加载和存储
第三个为带有后索引立即偏移量的加载和存储
三、条件标志和相关说明
标记是表示某些状态的内存块,存储在CPSR和SPSR寄存器中。
根据最近执行的带有特殊后缀“s”的ALU指令设置位。
MOV {S} {cond} Rd, Operand2
这些位可以用于后续指令的条件执行。
分类:
N:如果结果为负,则指令设置N标志。在实例中,N被设置为结果的两个补号(31)位
Z:如果结果为零,则设置Z标志。
C:Carry或Unsigned Overflow。如果无符号操作的结果溢出32为结果寄存器,则设置 C标志。
V:与C标志相同,但用于有符号的操作。
四、关于部分标志的使用
1、分支到目标地址
B{cond} label
Branch将CPU的执行重定向到一个由标签指示的新位置。标签是表示指令或数据的内存地址的符号。
例:
2、条件代码
3、问题思考和解决
假设我们想要开发一个函数来计算三个数字的和。这三个数字分别存储在r0, r1和r2中。总和 应该放入r5。我们希望在任何需要的时候调用这个函数。使用branch。我们可以通过它 的标签跳转到求和函数。但是我们如何确保程序可以返回到求和的位置函数是否被调用,如 果有多个地方调用它?我们可以在寄存器中标记它,然后在求和函数中使用if/else跳回相应的 位置。
解决方案:
使用Branch with link / Exchange
BL{cond} label
BX{cond} Rm
BL指令使分支标记,并将下一条指令的地址复制到LR。
BX指令导致Rm中包含的地址的一个分支。