在 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 位数字,我们需要掩码序列 b10000000
、b01000000
、...、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
我正在尝试使用 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
.
随后,要实际打印 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 位数字,我们需要掩码序列 b10000000
、b01000000
、...、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