Printing a binary number in LC-3 Assembly

青春壹個敷衍的年華 提交于 2019-12-02 09:58:43
Scott Caldwell

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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!