• 沒有找到結果。

Thumb 伪指令

在文檔中 1.1 嵌入式系统 (頁 119-122)

第4章 ARM7TDMI(-S)指令系统

… DATA_BUF

6. Thumb 伪指令

ADR——小范围的地址读取伪指令

ADR 指令将基于 PC 相对偏移的地址值读取到寄存器中。ADR 伪指令格式如下:

ADR register,expr

其中: register 加载的目标寄存器。

expr 地址表达式。偏移量必须是正数并小于 1KB。Expr 必须局部定义,

不能被导入。

ADR 伪指令举例如下:

ADR R0,TxtTab

TxtTab

DCB "ARM7TDMI",0

LDR——大范围的地址读取伪指令

LDR 伪指令用于加载 32 位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,

LDR 伪指令被编译器替换成一条合适的指令。若加载的常数未超出 MOV 的范围,则使用 MOV 或 MVN 指令代替该 LDR 伪指令,否则汇编器将常量放入文字池,并使用一条程序相 对偏移的LDR 指令从文字池读出常量。LDR 伪指令格式如下:

LDR register,=expr/label-expr

其中: register 加载的目标寄存器。

expr 32 位立即数。

label-expr 基于 PC 的地址表达式或外部表达式。

- - 110 LDR 伪指令举例如下:

LDR R0,=0x12345678 ; 加载32 位立即数 0x12345678 LDR R0,=DATA_BUF+60 ; 加载DATA_BUF 地址+60

LTORG ; 声明文字池

从 PC 到文字池的偏移量必须是正数并小于 1KB。

与 Thumb 指令的 LDR 相比,伪指令的 LDR 的参数有“=”号。

NOP——空操作伪指令

NOP 伪指令在汇编时将会被代替成 ARM 中的空操作,比如可能为 MOV R0,R0 指令 等。NOP 伪指令格式如下:

NOP

NOP 可用于延时操作。

2.6 本章小结

本章详细地价绍了ARM 指令集、Thumb 指令集,并列出了各条指令的编码格式及相关 应用举例,使读者对ARM7TDMI(-S)的指令系统有全面的了解。

思考与练习 1 基础知识

a) ARM7TDMI(-S)有几种寻址方式?LDR R1,[R0,#0x08]属于哪种寻址方式?

b) ARM 指令的条件码有多少个?默认条件码是什么?

c) ARM 指令中第二个操作数有哪几种形式?列举 5 个 8 位图立即数。

d) LDR/STR 指令的偏移形式有哪 4 种?LDRB 和 LDRSB 有何区别?

e) 请指出 MOV 指令与 LDR 加载指令的区别及用途。

f) CMP 指令的操作是什么?写一程序,判断 R1 的值是否大于 0x30,是则将 R1 减去 0x30。

g) 调用子程序是用 B 还是用 BL 指令?请写出返回子程序的指令?

h) 请指出 LDR 伪指令的用法。指令格式与 LDR 加载指令的区别是什么?

i) ARM 状态与 Thumb 状态的切换指令是什么?请举例说明。

j) Thumb 状态与 ARM 状态的寄存器有区别吗?Thumb 指令对哪些寄存器的访问受到 一定即制?

k) Thumb 指令集的堆栈入栈、出栈指令是哪两条?

l) Thumb 指令集的 BL 指令转移范围为何能达到±4MB?其指令编码是怎样的?

2 有符号和无符号加法

下面给出A 和 B 的值,您可先手动计算 A+B,并预测 N、Z、V 和 C 标志位的值。然 后修改程序清单4.1 中 R0、R1 的值,将这两个值装载到这两个寄存器中(使用 LDR 伪指令,

如LDR R0,=0x FFFF0000),使其执行两个寄存器的加法操作。调试程序,每执行一次加法 操作就将标志位的状态记录下来,并将所得结果与您预先计算得出的结果相比较。如果两个 操作数看作是有符号数,如何解释所得标志位的状态?同样,如果这两个操作数看作是无符

- - 111 号数,所得标志位又当如何理解?

0xFFFF000F 0x7FFFFFFF 67654321 (A) + 0x0000FFF1 + 0x02345678 + 23110000 (B)

结果: ( ) ( ) ( )

3 数据访问

把下面的C 代码转换成汇编代码。数组 a 和 b 分别存放在以 0x4000 和 0x5000 为起始 地址的存储区内,类型为long(即 32 位)。把编写的汇编语言进行编译连接,并进行调试。

for (i=0; i<8; i++) { a[i] = b[7-i];

}

4 阶乘计算

计算一个数n 的阶乘,即 n!=n*(n-1)*(n-2)…(1)。

给定n 的值后,整个算法就是不断使当前值与前一次乘数减一所得值相乘,这里所说的 当前值即是乘法运算的结果。程序不断循环执行乘法操作,每次循环先将乘数减一,若所得 值为0 则循环结束。在程序中,使用条件执行的思想来做乘法。在编写含有循环和转移指令 的程序时,由于可以用 Z 标志来迅速判断是否到达循环次数,很多编程者通常使用一个非 零数向下计数而不是向上计数的方法来起动程序。

请填充下面的代码段,并加入相应的段声明信息,然后调试程序的正确性。设定n 的值 为10,说明程序执行结果,并观察程序运行之前和之后寄存器的内容。

FACTORIAL MOV R6,#10 ; 10 存放到 R6 (n)

MOV R4,R6 ; 初始化保存结果的寄存器 R4 (n 的结果) LOOP SUBS _____________ ; 本次乘数减一

MULNE _____________ ; 乘法运算

BNE LOOP ; 如果循环未结束,转去执行下次循环

- - 112

在文檔中 1.1 嵌入式系统 (頁 119-122)