本章目标
2.8 其他指令
到目前为止,我们已经介绍了下列指令 : Load、Store、Move、Clear、Add、Subtract、
Branch、Call 和 Return。使用这些指令和表 2-1 中的寻址方式,我们已经可以编写程序来说明 机器指令的执行序列了,包括转移和子程序的链接。在这一节中,我们再介绍几条指令,这些 指令是在大部分指令集中都存在的。
2.8.1 逻辑指令
按位AND(与)、OR(或)和 NOT(非)等逻辑操作,是数字电路的基本构件,附录 A 中对数字电路进行了介绍。逻辑操作也可以在软件中执行,用一些指令将这些操作独立或是并 行地施加于一个字或一个字节的所有位上。例如,指令
And R4, R2, R3
FP
FP
param3
2028 param1 param2
SUB2 的栈结构
SUB1 的栈结构
原来的TOS [R3] 来自 SUB1
[R2] 来自 SUB1 [FP] 来自 SUB1
[R5] 来自主程序 [R4] 来自主程序 [R3] 来自主程序 [R2] 来自主程序 [FP] 来自主程序
图2-22 图 2-21 的栈结构
对寄存器R2 和 R3 中的操作数进行按位 AND(与)运算,并且将结果存在 R4 中。这条指令 的立即数形式可能是:
And R4, R2, #Value
在这里Value 本来是一个 16 位的逻辑值,通过向其 16 个最高有效位填充 0 来将其扩展到 32 位。
下面考虑这条逻辑指令的应用。假设有四个ASCII 字符被保存在 32 位的寄存器 R2 中。在某个任务中,我们希望确定最右边的字符是否为Z,如果是 Z,就执行条件转移到 FOUNDZ。从第 1 章的表 1-1 中我们找到了字符 Z 的 ASCII 码是 01011010,用十六进制记数 法表示为5A。这三条指令的序列
And R2, R2, #0xFF Move R3, #0x5A Branch_if_[R2]=[R3] FOUNDZ
实现了所期望的动作。And 指令将 R2 中最左边三个字符的所有位都清 0,而使最右边的字符 保持不变。这是由于使用了一个右端8 位是 1,左端 24 位是 0 的立即操作数。Move 指令将 十六进制值5A 加载到 R3 中。由于 R2 和 R3 最左边的 24 位都为 0,所以 Branch 指令将 R2 中 右端的剩余字符与字符Z 的二进制表示形式进行比较,如果相匹配,就产生一个到 FOUNDZ 的跳转。
2.8.2 移位和循环移位指令
有很多应用需要将一个操作数的位向右或向左移动指定数量的位。这个移动过程如何被 执行,取决于操作数是一个有符号数还是一般的二进制码信息。对于一般的操作数,我们使用 逻辑移位。对于有符号数,我们使用算术移位,算术移位可以保持该数的符号不变。
1.逻辑移位
有两条逻辑移位指令,一条是左移(LShiftL),另一条是右移(LShiftR)。这些指令将一 个操作数移动一定数量的位,这个移动数量值由该指令中的一个计数操作数指定。逻辑左移指 令的一般形式为:
LShiftL Ri, Rj, count
该指令将寄存器Rj 的内容左移计数操作数所给定的位数,并把结果放到寄存器 Ri 中,而 Rj 的内容没有改变。计数操作数可以作为一个立即操作数给出,也可以包含在一个处理器寄存器 中。为了完善左移操作的描述,我们需要指明目的操作数右边空出位的值,并确定在左端移出 的位上发生了什么。空出的位置用0 填充。在不使用条件码标志的计算机中,移出的位被简单 地丢弃。在使用条件码标志的计算机中(将在2.10.2 节中讨论),这些位经过进位标志 C,然 后再被丢弃。将C 标志一起参与移位,这在对占用多个字的大数执行算术运算的时候是很有 用的。图2-23a 给出了一个例子,它将寄存器 R3 的内容左移两位。逻辑右移指令 LShiftR 除 了向右移以外,其他工作方式与逻辑左移指令是相同的。图2-23b 说明了这种操作。
2.数字打包示例
考虑以下的小任务,它说明了移位操作和逻辑操作的用法。假设两个ASCII 码表示的十 进制数存储在存储器的字节单元LOC 和 LOC+1 中。我们希望将这些十进制数用 4 位 BCD 码 表示,并将两个数的BCD 码都存放到一个单独的字节单元 PACKED 中。上述的结果被称为是 打包BCD 码(packed-BCD)格式的。第 1 章的表 1-1 给出了对应于十进制数 BCD 码的 ASCII 码最右边的四位数。因此,我们需要做的就是在LOC 和 LOC+1 中提取出低 4 位的内容,然后
65~ 67
68
将它们拼接成一个单字节放在PACKED 中。
StoreByte 指令将源寄存器中 最右边的字节写入到指定的目
Move R2, #LOC LoadByte R3, (R2) LShiftL R3, R3, #4 Add R2, R2, #1 LoadByte R4, (R2) And R4, R4, #0xF Or R3, R3, R4 StoreByte R3, PACKED
R2 指向数据
操作数的位被简单地进行循环。在另一种版本里,循环中包括了C 标志。图 2-25 给出了在循 环中包含或不包含C 标志的循环左移和循环右移操作。要注意的是,当循环中不包括 C 标志 时,C 标志中仍然保留着寄存器尾部的最后一个移出位。OP 码 RotateL、RotateLC、RotateR 和RotateRC 表示执行循环移位操作的指令。
Multiply Rk, Ri, Rj 执行的操作为: Divide Rk, Ri, Rj
它执行的操作是: