在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...
这些都不是特别有效.我正在拔头发,试图找出执行此操作的正确方法,但是我想做的一切都依赖于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位数字,我们将需要掩码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
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屋!