如何在 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,你有内置的右移指令。否则,你需要写一个循环。