在 LC-3 中,OUTtrap 子例程获取当前存储在寄存器R0 中的值,找到相应的 ASCII 值并将其输出到控制台,而PUTtrap 子例程获取存储在 @ 中的值987654324@ 作为内存,并遍历存储在该地址的所有数据,将每个字节作为 ASCII 输出到控制台,直到找到一个 NULL 字符。
在您给出的示例中,PUTS 将打印出 b10000110 的 ASCII 表示,然后是垃圾,直到它碰巧遇到 NULL 字符,而 OUT 将简单地打印 b10000110 的 ASCII 表示。
随后,要实际打印 0 或 1,我们必须打印这些数字的 ASCII 表示,而不是数字本身。所以,我们定义了两个词,一个用于 ASCII 字符0,另一个用于1。
ascii0 .fill x30
ascii1 .fill x31
因此,对于任何 1 位数字,我们可以通过简单的 if-else 分支和 OUT 子例程将其打印到控制台。
binary .fill b1
LD R1, binary
AND R0, R1, #1
BRnz else
LD R0, ascii1
BRnzp done
else LD R0, ascii0
done OUT
现在,我们必须将其扩展到 n 位。也就是说,我们必须将我们的 n 位数字分解成一系列我们可以轻松打印的 1 位数字。为此,我们只需要一个简单的AND 和第 ith 位的掩码(例如,给定 8 位数字 b10000110,以确定第 3rd sup> 最低有效位,我们将使用掩码 b00000100)。因此,对于 8 位数字,我们将需要掩码序列b10000000、b01000000、...、b00000001。有几种方法可以做到这一点,例如从b10000000 开始,每个位左移/乘以 2,但是为了简单起见,我们将使用查找表。
masks .fill b10000000
.fill b01000000
.fill b00100000
.fill b00010000
.fill b00001000
.fill b00000100
.fill b00000010
.fill b00000001
要在打印出每个位之前选择掩码,我们可以使用一个简单的 for 循环分支。
AND R4, R4, #0 ;clears the register we will count with
LD R1, binary
LEA R2, masks ;finds the address in memory of the first mask
loop LDR R3, R2, #0 ;load the mask from the address stored in R2
ADD R2, R2, #1 ;next mask address
AND R0, R1, R3
;print out 1-bit number
ADD R4, R4, #1
ADD R0, R4, #-8 ;sets condition bit zero when R4 = 8
BRn loop ;loops if R4 < 8
最后,我们完成了程序。
.ORIG x3000
AND R4, R4, #0 ;clears the register we will count with
LD R1, binary
LEA R2, masks ;finds the address in memory of the first mask
loop LDR R3, R2, #0 ;load the mask from the address stored in R2
ADD R2, R2, #1 ;next mask address
AND R0, R1, R3
BRnz else
LD R0, ascii1
BRnzp done
else LD R0, ascii0
done OUT
ADD R4, R4, #1
ADD R0, R4, #-8 ;sets condition bit zero when R4 = 8
BRn loop ;loops if R4 < 8
HALT
masks .fill b10000000
.fill b01000000
.fill b00100000
.fill b00010000
.fill b00001000
.fill b00000100
.fill b00000010
.fill b00000001
ascii0 .fill x30
ascii1 .fill x31
binary .fill b10000110
.END