在LC-3组装件中打印二进制数 [英] Printing a binary number in LC-3 Assembly

查看:145
本文介绍了在LC-3组装件中打印二进制数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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...

这些都不是特别有效.我正在拔头发,试图找出执行此操作的正确方法,但是我想做的一切都依赖于binary是字符串,而我做不到.

解决方案

在LC-3中,OUT trap子例程获取当前存储在寄存器R0中的值,找到相应的ASCII值并将其输出到控制台,而PUT trap子例程将存储在R0中的值用作内存,并遍历该地址中存储的所有数据,将每个字节作为ASCII输出到控制台,直到找到NULL字符为止.

在您给出的示例中,PUTS将打印出b10000110的ASCII表示形式,然后进行垃圾处理,直到碰巧出现NULL字符为止,而OUT将仅打印出b10000110的ASCII表示形式./p>

随后,要实际打印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和第i 位的掩码(例如,给定8位数字b10000110来确定3 rd 最低有效位,我们将使用掩码b00000100).因此,对于8位数字,我们将需要掩码b10000000b01000000,...,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

I'm trying to print a binary number to the console using LC-3 assembly.

What I've tried so far includes (but isn't limited to):

        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 of this works particularly well. I'm pulling my hair out trying to figure out the proper way to do this, but everything I'm thinking of relies on binary being a string, which I can't do.

解决方案

In LC-3, the OUT trap subroutine takes the value currently stored in register R0, finds the corresponding ASCII value and outputs it to the console, while the PUT trap subroutine takes the value stored in R0 as a memory, and iterates through all the data stored at that address, outputting each byte as ASCII to the console, until it finds a NULL character.

In the example you gave, PUTS will print out the ASCII representation of b10000110, followed by garbage until it happens to hit a NULL character whereas OUT will simply print the ASCII representation of b10000110.

Subsequently, to actually print a 0 or a 1, we must print the ASCII representation of those numbers, not the numbers themselves. So, we define two words, one for the ASCII character 0, and the other for 1.

ascii0  .fill x30
ascii1  .fill x31

So, for any 1-bit number, we can print it to the console with a simple if-else branch and the OUT subroutine.

binary  .fill b1
        LD  R1, binary
        AND R0, R1, #1
        BRnz else
        LD  R0, ascii1
        BRnzp done
else    LD  R0, ascii0
done    OUT

Now, we must extend this to n-bits. That is to say that we must break our n-bit number into a series of 1-bit numbers that we can easily print. To achieve this, all we need is a simple AND and a mask for the ith bit (e.g. given the 8-bit number b10000110, to determine the 3rd least significant bit, we would use the mask b00000100). So, for an 8-bit number, we will need the sequence of masks b10000000, b01000000, ..., b00000001. There are several ways to do this, such as starting with b10000000 and left-shifting/multiplying by 2 for each bit, however for the sake of simplicity we will use a lookup table.

masks   .fill b10000000
        .fill b01000000
        .fill b00100000
        .fill b00010000
        .fill b00001000
        .fill b00000100
        .fill b00000010
        .fill b00000001

To choose the mask before we print out each bit, we can use a simple for-loop branch.

        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

Finally, we have our completed program.

        .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

这篇关于在LC-3组装件中打印二进制数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆