-3

このコードが機能しない理由を教えてください。

.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
4

2 に答える 2

0

このコードで達成したいことの詳細をお知らせください。また、次の行があるためJMP @WITHNEG、このコード行で@SUB : MOV AL, NUM1 CMP AL, NUM2 JG @WITHOUTNEG JMP @WITHNEGはまったく不要です。行@WITHNEG:ごとの実行スキームによると、JGが満たされない場合、次の行は何があっても実行されます。

もう 1 つの要求は、各命令を 1 行に書き込むことです。これを流暢に読んで理解するのは大変です。

またcode tags、コードを書くときはいつでも使用してください。

ありがとうございました :)

于 2013-09-12T17:53:53.393 に答える
0

コードがフォーマットされたので、少し理解しやすくなりました。

変数の 1 つを修正しましょう。

OPERAND DB 13,10, "ENTER OPERAND:,

次のようにする必要があります。

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

次に文字を「取得」するとき、それは文字のASCIIコードであるため、単一の文字の場合、ここで行うように0ではなく、48または「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 @PRINTJMP @EXIT

@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 

なぜすべて大文字でコードを書いているのか疑問に思う必要がありますか?!?! コードが非常に読みにくくなります。また、入力した演算子が許可されている演算子の 1 つであるかどうかも確認する必要があります。

また、このコードは 9 以下の数値には問題ありませんが、それ以上の数値の場合は、ASCII に変換する別のコードが必要になります。

于 2013-09-13T02:03:25.980 に答える