Printing a binary number in LC-3 Assembly

2019-03-04 14:27发布

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.

标签: assembly lc3
1条回答
Fickle 薄情
2楼-- · 2019-03-04 14:46

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
查看更多
登录 后发表回答