在 LC-3 汇编中打印二进制数

Printing a binary number in LC-3 Assembly

我正在尝试使用 LC-3 程序集将二进制数打印到控制台。

目前我尝试过的包括(但不限于):

        binary .fill b10000110
        lea r0, binary
        puts ; prints garbage
        ld r0, binary
        out ; prints 0 (I know it only prints one character but I don't know why it chooses to print 0)
        lea r1, binary
        and r2, r2, #0
loop    ldr r0, r1, r2
        out
        add r2, r2, #1
        and r3, r3, #0
        not r3, r2
        add r3, r3, #1
        add r3, r3, #8 ; I know all the binary numbers will be exactly 8 bits long
        brz end
        add r3, r3, #0 ; to be safe
        brnzp loop
end
        ; more code...

None这个效果特别好。我绞尽脑汁想找出正确的方法来做这件事,但我想的一切都依赖于 binary 是一个字符串,我做不到。

在LC-3中,OUT trap子程序获取寄存器R0中当前存储的值,找到对应的ASCII值并输出到控制台,而PUT trap 子程序将 R0 中存储的值作为内存,并遍历存储在该地址的所有数据,将每个字节作为 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 最低有效位,我们将使用掩码 b00000100)。因此,对于 8 位数字,我们需要掩码序列 b10000000b01000000、...、b00000001。有几种方法可以做到这一点,例如从 b10000000 和 left-shifting/multiplying 开始,每个位加 2,但是为了简单起见,我们将使用查找 table.

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