You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LC-3汇编计算器乘法除法输出方块问号问题修复咨询

LC-3汇编计算器乘法除法输出方块问号问题修复

问题现象

运行代码时加法、减法功能正常,但乘法和除法无有效输出(显示方块问号),运行输出如下:

ENTER FIRST OPERAND : 4
ENTER SECOND OPERAND: 2
ADDITION: 6
SUBTRACTION: 2
MULTIPLICATION:
DIVISION:
----- Halting the processor -----

错误原因

  1. 操作数被覆盖:减法操作中修改了寄存器R2的原始值(取补码),导致乘法、除法使用错误的操作数进行计算。
  2. 乘法逻辑混乱:循环计数器初始化及条件判断错误,累加逻辑未基于原始输入值执行。
  3. 除法逻辑完全错误:当前代码是累加除数而非执行“被除数减除数计数”的除法逻辑,完全不符合需求。

修复步骤及代码修改

1. 保存原始操作数

在读取两个操作数后,立即将原始值保存到备用寄存器,避免后续操作覆盖:

; GET THE SECOND OPERAND
    lea R0, getop2
    puts
    getc ; Read the next character
    out ; Echo the character
    add R2, R0, R3 ; second operand in R2
    ; 保存原始操作数到R5、R7
    add R5, R1, #0 ; R5 = 原始第一个操作数
    add R7, R2, #0 ; R7 = 原始第二个操作数

2. 修复减法逻辑(避免覆盖原始操作数)

使用保存的原始值进行减法计算,不修改R7中的原始第二个操作数:

;;;;;;;;;;;;;;;;;;;;;; SUBTRACTION FIX
;Get twos compliment of second operand
    NOT R2, R7
    ADD R2, R2, #1
; Output a Message
    LEA R0, SUB_RESULT
    PUTS

; Perform subtraction by addition
    ADD R0,R5,R2    ; 使用原始操作数R5和R7的补码
    BRZP POS        ; Result is positive 
    ADD R4, R0, #0  ; Result is negative. Save R0
    
; Result is negative, display ‘-‘ sign
    LEA R0, MINUS   ; Result negative. Display '-'
    PUTS
    ADD  R0, R4, #0 ; R0 <- R4
    NOT R0, R0      ; Take twos complement of result
    ADD R0, R0, #1
POS LD R3, PLUS30
    ADD R0, R3, R0  ;Converts to ASCII digit
    OUT         ;Display Result

3. 修复乘法逻辑

基于原始操作数实现“累加第一个数共第二个数次”的乘法逻辑:

;;;;;;;;;;;;;;;;;;;;;; MULTIPLICATION FIX
LEA R0, MUL_RESULT  ; Display multiplication result message
    PUTS
    AND R3, R3, #0      ; R3作为累加器,初始化为0
    ADD R2, R7, #0      ; 用原始第二个操作数作为循环次数
MUL_LOOP ADD R3, R3, R5     ; 累加原始第一个操作数
        ADD R2, R2, #-1     ; 循环次数减1
        BRp MUL_LOOP        ; 次数大于0则继续循环
        ; 转换为ASCII并输出
        add R0, R3, R6
        OUT

4. 修复除法逻辑

实现“被除数减除数,计数减的次数”的除法逻辑:

;;;;;;;;;;;;;;;;;;;;;; DIVISION FIX
; Division
LEA R0, DIV_RESULT  ; Display division result message
PUTS
AND R4, R4, #0      ; R4作为商,初始化为0
ADD R1, R5, #0      ; 用原始第一个操作数作为被除数
ADD R2, R7, #0      ; 用原始第二个操作数作为除数
DIV_LOOP 
    ; 计算除数的补码(用于减法)
    NOT R2, R2
    ADD R2, R2, #1
    ADD R1, R1, R2     ; 被除数减除数
    BRN DIV_DONE        ; 结果为负则停止循环
    ADD R4, R4, #1      ; 商加1
    ADD R2, R7, #0      ; 恢复除数原始值
    BRnzp DIV_LOOP      ; 重复循环
DIV_DONE 
    add R0, R4, R6  ; Convert quotient to ASCII
    OUT

修复后完整代码

.ORIG x3000
;
; Program to add two numbers. Prompt user to enter the numbers.
; The numbers are ASCII characters. Convert them to integers by
; subtracting x30 from the ASCII code. Store the operands in
; registers R1 and R2.
; Add the two integers. Store the sum in R0. Convert the sum to
; an ASCII character by adding x30 to it. Otherwise, you will not
; be able to print it.
;

    ld R3, MINUSx30 ; R3 <- x-30 (ASCII 0)
    ld R6, PLUSx30

; GET THE FIRST OPERAND
    lea R0, getop1 ;Prompt user
    puts
    getc ; Read the character
    out ; Echo the character
    add R1, R0, R3 ; first operand is in R1

; GET THE SECOND OPERAND
    lea R0, getop2
    puts
    getc ; Read the next character
    out ; Echo the character
    add R2, R0, R3 ; second operand in R2
    ; 保存原始操作数到R5、R7
    add R5, R1, #0 ; R5 = 原始第一个操作数
    add R7, R2, #0 ; R7 = 原始第二个操作数

; OUTPUT A NEXT-LINE CHARACTER (10)
    and R0, R0, #0
    add R0, R0, #10 ;#10 is Line feed in ASCII
    out

; Output a Message
    LEA R0, ADD_RESULT
    PUTS

; ADD the two numbers, Convert result to ASCII & Display
    add R0, R1, R2 ; R0 <- R1 + R2
    ld R3, PLUSx30 ; R3 <- x30
    add R0, R0, R3 ; R0 <- R0 +x30
    out ; Output result

;;;;;;;;;;;;;;;;;;;;;; SUBTRACTION FIX
;Get twos compliment of second operand
    NOT R2, R7
    ADD R2, R2, #1
; Output a Message
    LEA R0, SUB_RESULT
    PUTS

; Perform subtraction by addition
    ADD R0,R5,R2    ; 使用原始操作数R5和R7的补码
    BRZP POS        ; Result is positive 
    ADD R4, R0, #0  ; Result is negative. Save R0
    
; Result is negative, display ‘-‘ sign
    LEA R0, MINUS   ; Result negative. Display '-'
    PUTS
    ADD  R0, R4, #0 ; R0 <- R4
    NOT R0, R0      ; Take twos complement of result
    ADD R0, R0, #1
POS LD R3, PLUS30
    ADD R0, R3, R0  ;Converts to ASCII digit
    OUT         ;Display Result

;;;;;;;;;;;;;;;;;;;;;; MULTIPLICATION FIX
LEA R0, MUL_RESULT  ; Display multiplication result message
    PUTS
    AND R3, R3, #0      ; R3作为累加器,初始化为0
    ADD R2, R7, #0      ; 用原始第二个操作数作为循环次数
MUL_LOOP ADD R3, R3, R5     ; 累加原始第一个操作数
        ADD R2, R2, #-1     ; 循环次数减1
        BRp MUL_LOOP        ; 次数大于0则继续循环
        ; 转换为ASCII并输出
        add R0, R3, R6
        OUT

;;;;;;;;;;;;;;;;;;;;;; DIVISION FIX
; Division
LEA R0, DIV_RESULT  ; Display division result message
PUTS
AND R4, R4, #0      ; R4作为商,初始化为0
ADD R1, R5, #0      ; 用原始第一个操作数作为被除数
ADD R2, R7, #0      ; 用原始第二个操作数作为除数
DIV_LOOP 
    ; 计算除数的补码(用于减法)
    NOT R2, R2
    ADD R2, R2, #1
    ADD R1, R1, R2     ; 被除数减除数
    BRN DIV_DONE        ; 结果为负则停止循环
    ADD R4, R4, #1      ; 商加1
    ADD R2, R7, #0      ; 恢复除数原始值
    BRnzp DIV_LOOP      ; 重复循环
DIV_DONE 
    add R0, R4, R6  ; Convert quotient to ASCII
    OUT

    HALT ; Done
; DATA DECLARATIONS

getop1      .STRINGZ "\nENTER FIRST OPERAND : "
getop2      .STRINGZ "\nENTER SECOND OPERAND: "
ADD_RESULT  .STRINGZ "\nADDITION: "
SUB_RESULT  .STRINGZ "\nSUBTRACTION: "
MUL_RESULT  .STRINGZ "\nMULTIPLICATION: "
DIV_RESULT  .STRINGZ "\nDIVISION: "

MINUSx30 .FILL x-30
PLUSx30 .FILL x30
PLUS30  .FILL x30
MINUS30     .FILL x-30 
MINUS       .FILL X2D 
.end ; END OF CODE

内容的提问来源于stack exchange,提问作者jacksonsmithroger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:45:21