如何在 lc3 中进行数学运算(减法、乘法、阶乘)并将输出更改为十六进制?
How to do Math(subtraction, multiplication, factorial) and change output to hexadecimal in lc3?
我正在使用 LC3 模拟器,我想将输出从十进制更改为十六进制,正如我在标题中所说,我想知道如何在 LC3 中进行数学运算。我是 LC3 的新手,所以我真的需要 help.Thanks。
;
; Initialization
;
.ORIG x3000
LD R6, EMPTY ; R6 is the stack pointer
LD R5, PTR ; R5 is pointer to characters
AND R0, R0, #0
ADD R0, R0, #10 ; Print a new line
OUT
;
REDO LDR R3, R5, #0 ; R3 gets character
;
; Test character for end of file
;
ADD R4, R3, #-10 ; Test for end of line (ASCII xA)
BRz EXIT ; If done, quit
LD R4, ZERO
ADD R3, R3, R4 ; Get the decimal value from ASCII
JSR CONV
ADD R5, R5, #1
AND R4, R5, #1 ; check odd/even
BRz EVEN
ADD R2, R3, #0 ; Save the first operand to R2
LD R0, PLUS ; '+'
OUT
BRnzp REDO
EVEN LD R0, EQUAL ; '='
OUT
; Start calculation
ADD R3, R2, R3 ; The second operand is at R3
;
JSR CONV
AND R0, R0, #0
ADD R0, R0, #10 ; Print a new line
OUT
BRnzp REDO
;
; A subroutine to output a 3-digit decimal result.
;
CONV ADD R1, R7, #0 ; R3, R4, R5 and R7 are used in this subroutine
JSR Push
ADD R1, R3, #0 ; R3 is the input value
JSR Push
ADD R1, R4, #0
JSR Push
ADD R1, R5, #0
JSR Push
AND R5, R5, #0
OUT100 LD R4, HUNDRED
ADD R4, R3, R4 ; R3 - #100
BRn PRI100
LD R4, HUNDRED
ADD R3, R3, R4 ; R3 - #100
ADD R5, R5, #1
BRnzp OUT100
PRI100 LD R0, ASCII ; Load the ASCII template
ADD R0, R0, R5 ; Convert binary count to ASCII
OUT ; ASCII code in R0 is displayed.
AND R5, R5, #0
OUT10 ADD R4, R3, #-10
BRn PRI10
ADD R3, R3, #-10
ADD R5, R5, #1
BRnzp OUT10
PRI10 LD R0, ASCII ; Load the ASCII template
ADD R0, R0, R5 ; Convert binary count to ASCII
OUT ; ASCII code in R0 is displayed.
LD R0, ASCII
ADD R0, R0, R3 ; Convert binary count to ASCII
OUT ; ASCII code in R0 is displayed.
JSR Pop
ADD R5, R1, #0
JSR Pop
ADD R4, R1, #0
JSR Pop
ADD R3, R1, #0
JSR Pop
ADD R7, R1, #0
RET
Push STR R1, R6, #0 ; Stack Push
ADD R6, R6, #-1
RET
Pop ADD R6, R6, #1 ; Stack Pop
LDR R1, R6, #0
RET
; End of the subroutine
EXIT HALT ; Halt machine
PTR .FILL x3500
EMPTY .FILL x4000
ASCII .FILL x0030 ; '0'
ZERO .FILL xFFD0 ; -'0'
HUNDRED .FILL xFF00 ; -x100
EQUAL .FILL x003D ; '='
PLUS .FILL x002B ; '+'
MINUS .FILL x002D ; '-'
FACTOR .FILL x0021 ; '!'
MULT .FILL x002A ; '*'
CHAR_A .FILL x0041 ; 'A'
VAL .BLKW 1
.END
我从另一个文件获得输入,它们是这样的,所以在模拟器上它现在会显示为“002+003=005”。我希望它显示 '009+008=011'、'009-008=001'、'009*008=048'、'006!=2D0' 用于加法、减法、乘法和阶乘。
.ORIG x3500
HELLO .STRINGZ "9887766554433221\n" ;this is the other file
How do I do subtraction?
LC3没有减法指令。您需要做的是取第二个操作数的负数,并将其添加到第一个操作数。你如何否定第二个操作数? LC3 是一台 Two's Complement 机器。所以,你按位取反,然后加 1.
要将 R0 和 R1 中的两个数字相加,将结果放入 R0,请使用以下程序集:
ADD R0, R0, R1
要从 R0 中减去 R1(即 R0 - R1)并将结果放入 R0,请使用以下程序集:
NOT R1, R1
ADD R1, R1, #1
ADD R0, R0, R1
那是很多工作,但至少不是乘法!
How do I do multiplication?
...
很好。
乘法有两种方法。首先是重复添加。假设您将 5 乘以 4。
5
5
5
+5
--
20
所以,你写一个循环,重复加5、4次。如果您要乘以大数,这会很快变得笨拙。
第二种方法是使用掩码,每次循环将掩码和其中一个操作数左移一次。这允许您仅在 16 个循环中进行乘法运算。
How do I do factorial?
您创建了一个乘法子例程,并重复使用它来创建一个阶乘子例程。
I want to change the output from decimal to hexadecimal
你很幸运,因为十六进制在 LC3 中比十进制更容易处理。你可以做的是取出数字的前 4 位,将它们右移,然后使用查找 table 来决定要打印的十六进制数字。然后,将您的原始数字左移 4 位。这样做 4 次,您将打印出数字。
这是一个例子:
; assume R0 has the 4-bit number we want to convert to hex
LEA R1, lookup
ADD R0, R0, R1 ; go to the cell pointed to by R1, and advance the pointer
; by the number in R1
LDR R0, R0, #0 ; load the cell pointed to by R0 into R0
OUT ; print hex
lookup .STRINGZ "0123456789ABCDEF"
向右移动可能很烦人,这取决于您使用的 LC3 版本。如果你使用LC3b,你有内置的右移指令。否则,你需要写一个循环。
我正在使用 LC3 模拟器,我想将输出从十进制更改为十六进制,正如我在标题中所说,我想知道如何在 LC3 中进行数学运算。我是 LC3 的新手,所以我真的需要 help.Thanks。
;
; Initialization
;
.ORIG x3000
LD R6, EMPTY ; R6 is the stack pointer
LD R5, PTR ; R5 is pointer to characters
AND R0, R0, #0
ADD R0, R0, #10 ; Print a new line
OUT
;
REDO LDR R3, R5, #0 ; R3 gets character
;
; Test character for end of file
;
ADD R4, R3, #-10 ; Test for end of line (ASCII xA)
BRz EXIT ; If done, quit
LD R4, ZERO
ADD R3, R3, R4 ; Get the decimal value from ASCII
JSR CONV
ADD R5, R5, #1
AND R4, R5, #1 ; check odd/even
BRz EVEN
ADD R2, R3, #0 ; Save the first operand to R2
LD R0, PLUS ; '+'
OUT
BRnzp REDO
EVEN LD R0, EQUAL ; '='
OUT
; Start calculation
ADD R3, R2, R3 ; The second operand is at R3
;
JSR CONV
AND R0, R0, #0
ADD R0, R0, #10 ; Print a new line
OUT
BRnzp REDO
;
; A subroutine to output a 3-digit decimal result.
;
CONV ADD R1, R7, #0 ; R3, R4, R5 and R7 are used in this subroutine
JSR Push
ADD R1, R3, #0 ; R3 is the input value
JSR Push
ADD R1, R4, #0
JSR Push
ADD R1, R5, #0
JSR Push
AND R5, R5, #0
OUT100 LD R4, HUNDRED
ADD R4, R3, R4 ; R3 - #100
BRn PRI100
LD R4, HUNDRED
ADD R3, R3, R4 ; R3 - #100
ADD R5, R5, #1
BRnzp OUT100
PRI100 LD R0, ASCII ; Load the ASCII template
ADD R0, R0, R5 ; Convert binary count to ASCII
OUT ; ASCII code in R0 is displayed.
AND R5, R5, #0
OUT10 ADD R4, R3, #-10
BRn PRI10
ADD R3, R3, #-10
ADD R5, R5, #1
BRnzp OUT10
PRI10 LD R0, ASCII ; Load the ASCII template
ADD R0, R0, R5 ; Convert binary count to ASCII
OUT ; ASCII code in R0 is displayed.
LD R0, ASCII
ADD R0, R0, R3 ; Convert binary count to ASCII
OUT ; ASCII code in R0 is displayed.
JSR Pop
ADD R5, R1, #0
JSR Pop
ADD R4, R1, #0
JSR Pop
ADD R3, R1, #0
JSR Pop
ADD R7, R1, #0
RET
Push STR R1, R6, #0 ; Stack Push
ADD R6, R6, #-1
RET
Pop ADD R6, R6, #1 ; Stack Pop
LDR R1, R6, #0
RET
; End of the subroutine
EXIT HALT ; Halt machine
PTR .FILL x3500
EMPTY .FILL x4000
ASCII .FILL x0030 ; '0'
ZERO .FILL xFFD0 ; -'0'
HUNDRED .FILL xFF00 ; -x100
EQUAL .FILL x003D ; '='
PLUS .FILL x002B ; '+'
MINUS .FILL x002D ; '-'
FACTOR .FILL x0021 ; '!'
MULT .FILL x002A ; '*'
CHAR_A .FILL x0041 ; 'A'
VAL .BLKW 1
.END
我从另一个文件获得输入,它们是这样的,所以在模拟器上它现在会显示为“002+003=005”。我希望它显示 '009+008=011'、'009-008=001'、'009*008=048'、'006!=2D0' 用于加法、减法、乘法和阶乘。
.ORIG x3500
HELLO .STRINGZ "9887766554433221\n" ;this is the other file
How do I do subtraction?
LC3没有减法指令。您需要做的是取第二个操作数的负数,并将其添加到第一个操作数。你如何否定第二个操作数? LC3 是一台 Two's Complement 机器。所以,你按位取反,然后加 1.
要将 R0 和 R1 中的两个数字相加,将结果放入 R0,请使用以下程序集:
ADD R0, R0, R1
要从 R0 中减去 R1(即 R0 - R1)并将结果放入 R0,请使用以下程序集:
NOT R1, R1
ADD R1, R1, #1
ADD R0, R0, R1
那是很多工作,但至少不是乘法!
How do I do multiplication?
...
很好。
乘法有两种方法。首先是重复添加。假设您将 5 乘以 4。
5
5
5
+5
--
20
所以,你写一个循环,重复加5、4次。如果您要乘以大数,这会很快变得笨拙。
第二种方法是使用掩码,每次循环将掩码和其中一个操作数左移一次。这允许您仅在 16 个循环中进行乘法运算。
How do I do factorial?
您创建了一个乘法子例程,并重复使用它来创建一个阶乘子例程。
I want to change the output from decimal to hexadecimal
你很幸运,因为十六进制在 LC3 中比十进制更容易处理。你可以做的是取出数字的前 4 位,将它们右移,然后使用查找 table 来决定要打印的十六进制数字。然后,将您的原始数字左移 4 位。这样做 4 次,您将打印出数字。
这是一个例子:
; assume R0 has the 4-bit number we want to convert to hex
LEA R1, lookup
ADD R0, R0, R1 ; go to the cell pointed to by R1, and advance the pointer
; by the number in R1
LDR R0, R0, #0 ; load the cell pointed to by R0 into R0
OUT ; print hex
lookup .STRINGZ "0123456789ABCDEF"
向右移动可能很烦人,这取决于您使用的 LC3 版本。如果你使用LC3b,你有内置的右移指令。否则,你需要写一个循环。