用汇编语言得到余数和商

时间:2013-09-12 16:14:27

标签: assembly x86

你能帮忙解释为什么这段代码无效吗?

.MODEL SMALL 
.STACK 64 
.DATA

INPUT DB 13, 10, "Enter input : ","$" 
OPERAND DB 13,10, "ENTER OPERAND:,  
SUM DB 13,10, "The sum is : ","$" 
DIFF DB 13,10, "The difference is : ","$" 
MULTI DB 13,10, "The product is : ","$" 
DIVI DB 13,10, "The quotient is : ","$" 
MODULO DB 13,10, "The modulo is : ","$" 
NUM1 db ? 
NUM2 db ? 
OP db ? 
RES db ?

;-----------------------------------------------------

.CODE 
MAIN PROC NEAR

    MOV AX, @DATA 
    MOV DS, AX

    ; outputs "input" message 
    LEA DX, INPUT 
    MOV AH, 09h 
    INT 21h

    ; get first input 
    MOV AH, 01h 
    INT 21h 
    SUB AL, 0 
    MOV NUM1, AL

    ; get operand 
    MOV AH, 01h 
    INT 21h 
    MOV OP, AL

    ; get second input 
    MOV AH, 01h 
    INT 21h 
    SUB AL, 0 
    MOV NUM2, AL

    CMP OP, "+" 
    JE  @ADD

    CMP OP, "-" 
    JE  @SUB

    CMP OP, "*" 
    JE  @MULTIPLY

    CMP OP, "/" 
    JE  @DIVIDE

    CMP OP, "%" 
    JE  @MOD

@ADD : 
    ADD AL, NUM1 
    MOV RES, AL

    LEA DX, SUM 
    MOV AH, 09h 
    INT 21h 
    JMP @PRINT

@SUB : 
    MOV AL, NUM1 
    CMP AL, NUM2 
    JG  @WITHOUTNEG 
    JMP @WITHNEG

@WITHNEG : 
    MOV AL, NUM2 
    SUB AL, NUM1 
    MOV RES, AL

    LEA DX, DIFF 
    MOV AH, 09h 
    INT 21h

    MOV OP, "-" 
    MOV DL, OP 
    MOV AH,02h 
    INT 21h 
    JMP @PRINT

@WITHOUTNEG : 
    MOV AL, NUM1 
    SUB AL, NUM2 
    MOV RES, AL

    LEA DX, DIFF 
    MOV AH, 09h 
    INT 21h 
    JMP @PRINT

@MULTIPLY : 
    MOV AL, NUM1 
    IMUL NUM2 
    MOV RES, AL

    LEA DX, MULTI 
    MOV AH, 09h 
    INT 21h 
    JMP @PRINT

@DIVIDE : 
    XOR AX, AX 
    MOV AL, NUM1 
    IDIV NUM2 
    MOV RES, AL

    LEA DX, DIVI 
    MOV AH, 09h 
    INT 21h 
    JMP @PRINT

@MOD : 
    XOR AX, AX 
    MOV AL, NUM1 
    IDIV NUM2 
    MOV RES, AH

    LEA DX, MODULO 
    MOV AH, 09h 
    INT 21h 
    JMP @PRINT

@PRINT : 
    XOR AX, AX

    MOV AL, RES 
    MOV BL, 10 
    IDIV BL

    ADD AL, 0 
    MOV DL, AL 
    MOV AH,02h 
    INT 21h

    ADD AH, 0 
    MOV DL, AH 
    MOV AH,02h 
    INT 21h 
    JMP @EXIT

@EXIT : 
    MOV AH,4Ch 
    INT 21h

MAIN ENDP

;----------------------------------------------------------------

END MAIN

2 个答案:

答案 0 :(得分:0)

请提供有关您希望通过此代码实现的目标的更多详细信息。此代码JMP @WITHNEG上的@SUB : MOV AL, NUM1 CMP AL, NUM2 JG @WITHOUTNEG JMP @WITHNEG完全没必要,因为下一行是@WITHNEG:。根据逐行执行方案,如果不满足JG,下一行将被执行无论如何。

另一个请求是每行写入每条指令。这很流畅,可以流利地阅读并理解它。

另外,在编写代码时请使用code tags

谢谢:)

答案 1 :(得分:0)

既然您的代码已经过格式化,那么它就会更容易理解。

让我们修复你的一个变量:

OPERAND DB 13,10, "ENTER OPERAND:,

应该是:

OPERAND DB 13,10, "ENTER OPERAND:", "$"

接下来当你“得到”一个字符时,它是字符的ASCII码,所以对于单个字符,要转换为你减去48或“0”的数字,而不是你在这里做的0:

; get first input 
MOV AH, 01h 
INT 21h 
SUB AL, 0 
MOV NUM1, AL

应该是:

; get first input 
MOV AH, 01h 
INT 21h 
SUB AL, "0" 
MOV NUM1, AL

看到区别?现在,您可以对其他输入进行更正。

接下来,您需要在OP比较后进行无条件跳转,否则如果用户没有输入正确的运算符,它将直接转到@ADD

CMP OP, "%" 
JE  @MOD
jmp @EXIT   ; <----- added

您的@MOD代码不需要JMP @PRINT,因为无论如何它将“落入”您的打印例程,在打印例程结束时JMP @EXIT也是如此。< / p>

@PRINT : 

XOR AX, AX

MOV AL, RES 
MOV BL, 10 
IDIV BL

ADD AL, "0" 
MOV DL, AL 
MOV AH,02h 
INT 21h

ADD AH, 0 
MOV DL, AH 
MOV AH,02h 
INT 21h 
JMP @EXIT

不确定为什么这样做:

MOV BL, 10 
IDIV BL

不需要。 现在,要将“数字”转换回其ASCII字符,您可以反转为输入所做的操作 - 添加48或“0”

@PRINT : 
    XOR AX, AX

    MOV AL, RES 
    ADD AL, "0" 
    MOV DL, AL 
    MOV AH,02h 
    INT 21h

@EXIT : 
    MOV AH,4Ch 
    INT 21h 

我必须质疑为什么要在所有CAPS中编写代码?!?!它使代码更难阅读。您还应该检查输入的运算符是否是允许的运算符之一。

此外,此代码适用于小于或等于9的数字,任何更大的数字,您将需要不同的代码才能转换为ASCII。