案例4加减乘除四则运算

这是从网上下载下来的一个计算程序,能实现加、减、乘、除的计算。该程序接受的是16进制数。
执行时,需在文件名后直接跟上计算表达式,如在命令提示符下执行结果如下:
c:\masm>js 3+2

5
c:\masm>js 6*7

2A
c:\masm>js 10-4

c
c:\masm>js 12/3

6


汇编代码:

B_P     EQU BYTE PTR
W_P     EQU WORD PTR
D_P     EQU DWORD PTR
CODE    SEGMENT
ASSUME  CS:CODE,DS:CODE
        ORG 100H
;主程序开始
NEWSTAR:
        JMP STAR
        EVEN
NUM1    DW 0,0
NUM2    DW 0,0
NUM3    DW 0,0
JGV4    DW 0,0
YSF     LABEL WORD
YSF1    DB 0
YSF2    DB 0
JUV     DB 0
UV      DB 0
;使DS:SI指向第一有效字符
OVERS   LABEL NEAR
        CLD
        PUSH AX
OVERS1:
        LODSB
        CMP AL,' '
        JZ OVERS1
        CMP AL,9
        JZ OVERS1
        DEC SI
        CMP AL,13
        POP AX
        RET
;输出一个制表符
TAB     LABEL NEAR
        MOV AL,9
        JMP SHORT DISP
;输出一个回车换行符
CRLF    LABEL NEAR
        MOV AL,13
        CALL DISP
        MOV AL,10
;显示一个字符
DISP    LABEL NEAR
        PUSH AX
        PUSH DX
        MOV AH,2
        MOV DL,AL
        INT 21H
        POP DX
        POP AX
        RET
;检查是否为运算符
ISYSF   LABEL NEAR
        CLD
        LODSB
        CALL ISJJ
        JZ ISYSF1
        CALL ISII
        JZ ISYSF1
        DEC SI
ISYSF1:
        RET
;检查是否是加减运算
ISJJ    LABEL NEAR
        CMP AL,'+'
        JZ ISYSF1
        CMP AL,'-'
        RET
;检查是否为乘除运算
ISII    LABEL NEAR
        CMP AL,'*'
        JZ ISYSF1
        CMP AL,'/'
        JZ ISYSF1
        CMP AL,'\'
        RET
;数据输出
;CX=10 十进制
;CX=16 十六进制
DOUT    LABEL NEAR
        PUSH AX
        PUSH BX
        PUSH DX
        PUSH BP
        XOR BP,BP
DOUT1:
        INC BP
        PUSH AX
        MOV AX,DX
        XOR DX,DX
        DIV CX
        MOV BX,AX
        POP AX
        DIV CX
        PUSH DX
        MOV DX,BX
        OR BX,AX
        JNZ DOUT1
DOUT2:
        POP AX
        ADD AL,'0'
        CMP AL,'9'
        JBE DOUT3
        ADD AL,'A'-'9'-1
DOUT3:
        CALL DISP
        DEC BP
        JNZ DOUT2
        POP BP
        POP DX
        POP BX
        POP AX
        RET
;输入数据在DX:AX中返回
;CX=0 数据为10进制
;CX#0 数据为16进制
DATE    LABEL NEAR
        PUSH BX
        PUSH BP
        PUSH DI
        XOR AX,AX
        XOR DX,DX
DATE1:
        MOV DI,AX
        LODSB
        CMP AL,'0'
        JB DATE7
        CMP AL,'9'
        JA DATE6
DATE2:
        AND AX,0FH
        SHL DI,1
        RCL DX,1
        MOV BX,DI
        MOV BP,DX
        SHL DI,1
        RCL DX,1
        SHL DI,1
        RCL DX,1
        JCXZ DATE3
        SHL DI,1
        RCL DX,1
        Jmp short DATE4
DATE3:
        ADD DI,BX
        ADC DX,BP
DATE4:
        ADD AX,DI
        ADC DX,0
        JMP DATE1
DATE5:
        ADD AL,9
        JMP DATE2
DATE6:
        JCXZ DATE7
        CMP AL,'A'
        JB DATE7
        CMP AL,'F'
        JBE DATE5
        CMP AL,'a'
        JB DATE7
        CMP AL,'f'
        JBE DATE5
DATE7:
        MOV AX,DI
        DEC SI
        OR DI,DX
        POP DI
        POP BP
        POP BX
        RET
;数据1与数据2根据YSF1进行加减运算
JSJJ    LABEL NEAR
        MOV AX,NUM2
        MOV DX,NUM2+2
        CMP YSF1,'+'
        JZ JSJJ1
        SUB NUM1,AX
        SBB NUM1+2,DX
        JMP SHORT JSJJ2
JSJJ1:
        ADD NUM1,AX
        ADC NUM1+2,DX
JSJJ2:
        RET
;数据1与数据2根据YSF1进行乘除运算
JSII1   LABEL NEAR
        MOV BX,OFFSET NUM1
        JMP SHORT JSII2_1
;数据2与数据3根据YSF2进行乘除运算
JSII2   LABEL NEAR
        MOV BX,OFFSET NUM2
JSII2_1:
        DB 66H
        MOV AX,[BX]
        DB 66H
        MOV CX,[BX+4]
        CMP YSF2,'*'
        JNZ JSII2_2
        DB 66H
        IMUL CX
        JMP SHORT JSII2_3
JSII2_2:
        DB 66H
        CWD
        DB 66H
        IDIV CX
        CMP YSF2,'/'
        JZ JSII2_3
        DB 66H
        XCHG DX,AX
JSII2_3:
        DB 66H
        MOV [BX],AX
        RET
;显示结果
XUJG    LABEL NEAR
        MOV AX,JGV4
        MOV DX,JGV4+2
        MOV CX,10
        CMP UV,10
        JZ XUJG0
        MOV CX,16
XUJG0:
        TEST DX,8000H
        JZ XUJG1
        CMP UV,10
        JZ XUJG2
        CALL DOUT
XUJG2:
        NOT AX
        NOT DX
        ADD AX,1
        ADC DX,0
        PUSH AX
        CMP UV,10
        JZ XUJG3
        MOV AL,' '
        CALL DISP
        MOV AL,'('
        CALL DISP
XUJG3:
        MOV AL,'-'
        CALL DISP
        POP AX
        CMP UV,10
        JZ XUJG1
        CALL DOUT
        MOV AL,')'
        CALL DISP
        RET
XUJG1:
        CALL DOUT
        RET
;计算结果放入DX:AX中
JSJG    LABEL NEAR
        CALL JSJJ
        MOV AX,NUM1
        MOV DX,NUM1+2
        RET
;从DS:SI处取一个数据
LOADATE LABEL NEAR
        LODSB
        CMP AL,'('
        JZ LOADATE1
        DEC SI
        PUSH CX
        XOR CX,CX
        CMP UV,10
        JZ LOADATE0
        INC CX          ;取16进制数
LOADATE0:
        CALL DATE       ;取数据放入DX:AX中
        POP CX
        RET
LOADATE1:
        PUSH NUM1       ;保存数据1数据2及运算符
        PUSH NUM1+2
        PUSH NUM2
        PUSH NUM2+2
        PUSH YSF
        INC JUV
        MOV JGV4,0      ;结果值清零
        MOV JGV4+2,0
;进行四则运算
SZYS    LABEL NEAR
        CALL ISYSF      ;首字符是运算符?
        JZ SZYS2
        CALL LOADATE    ;不是,取数并保存
        MOV NUM1,AX
        MOV NUM1+2,DX
SZYS1:
        XOR AX,AX       ;数据2清零
        MOV NUM2,AX
        MOV NUM2+2,AX
        CALL ISYSF      ;下个是运算符?
        JZ SZYS3
        JNZ SZYS6
SZYS2:
        PUSH AX
        MOV AX,JGV4     ;将结果作为数据1
        MOV NUM1,AX
        MOV AX,JGV4+2
        MOV NUM1+2,AX
        POP AX
SZYS3:
        MOV YSF1,AL
        MOV YSF2,AL
        CALL ISJJ       ;是加减运算转
        JZ SZYS4
        CALL LOADATE    ;取数据2
        MOV NUM2,AX
        MOV NUM2+2,DX
        CALL JSII1      ;数据1与数据2根据YSF1进行乘除运算
        JMP SZYS1       ;    结果保存在数据1中
SZYS4:
        CALL LOADATE    ;取数据2并保存
        MOV NUM2,AX
        MOV NUM2+2,DX
SZYS4_1:
        CALL ISYSF
        JNZ SZYS6
        CALL ISJJ       ;运算符2是加减运算?
        JNZ SZYS5       ;不是转
        PUSH AX
        CALL JSJJ       ;数据1与数据2根据YSF1进行加减运算
        POP AX          ;    结果保存在数据1中
        MOV YSF1,AL     ;保存新的运算符
        JMP SZYS4
SZYS5:
        MOV YSF2,AL     ;保存运算符2
        CALL LOADATE    ;取数据3
        MOV NUM3,AX
        MOV NUM3+2,DX
        CALL JSII2      ;数据2与数据3根据YSF2进行乘除运算
        JMP SZYS4_1     ;    结果保存在数据2中
SZYS6:
        MOV CL,AL
        CMP AL,13
        JNZ SZYS9
SZYS7:
        CALL JSJG
        CMP JUV,0
        JZ SZYS8
        DEC JUV
        POP YSF
        POP NUM2+2
        POP NUM2
        POP NUM1+2
        POP NUM1
        RET
SZYS8:
        CMP CL,')'
        JZ SZYS10
        MOV JGV4,AX
        MOV JGV4+2,DX
        JNZ SZYS12
SZYS9:
        CMP AL,')'
        JNZ SZYS11
        INC SI
        JMP SZYS7
SZYS10:
        MOV NUM1,AX
        MOV NUM1+2,DX
        JMP SZYS1
SZYS11:
        STC
        RET
SZYS12:
        CLC
        RET
;数制处理
UVIL    LABEL NEAR
        PUSH SI
UVIL1:
        LODSB
        CMP AL,' '
        JZ UVIL2
        CMP AL,9
        JZ UVIL2
        CMP AL,13
        JZ UVIL4
        JNZ UVIL1
UVIL2:
        MOV BX,SI
        CALL OVERS
        JZ UVIL3
        LODSW
        CALL OVERS
        POP SI
        JNZ SZYS11
        CMP AX,'01'
        JNZ SZYS11
        PUSH SI
        MOV UV,10
UVIL3:
        MOV AL,13
        MOV [BX-1],AL
UVIL4:
        POP SI
        CLC
        RET
;预置结果
YVJG    LABEL NEAR
        MOV AH,52H
        INT 21H
        MOV AX,ES:[BX-2]
        MOV DS,AX
        MOV AX,DS:[0CH]
        MOV CS:JGV4,AX
        MOV AX,DS:[0EH]
        MOV CS:JGV4+2,AX
        PUSH CS
        POP DS
        PUSH CS
        POP ES
        RET
;保存结果
BCJG    LABEL NEAR
        MOV AH,52H
        INT 21H
        MOV AX,ES:[BX-2]
        MOV DS,AX
        MOV AX,CS:JGV4
        MOV DS:[0CH],AX
        MOV AX,CS:JGV4+2
        MOV DS:[0EH],AX
        PUSH CS
        POP DS
        PUSH CS
        POP ES
        RET
STAR:
        MOV SI,81H
        CLD
        CALL OVERS
        JNZ STAR1
STAR0:
        MOV DX,OFFSET MESS1
        JMP STAR4
STAR1:
        CALL YVJG
        CALL UVIL
        JB STAR0
        MOV SAVESP,SP
        CALL SZYS
        MOV SP,SAVESP
        MOV DX,OFFSET MESS2
        JB STAR4
        CALL CRLF
        CALL XUJG
        CALL BCJG
        MOV DX,OFFSET MESS3
STAR4:
        MOV AH,9
        INT 21H
        INT 20H
SAVESP  DW 0
MESS1   DB 13,10,'  Syntax:',13,10
        DB '     JS  <Expression>  [10]',13,10,'$'
MESS2   DB 'Error in expression !$'
MESS3   DB 13,10,'$'
CODE    ENDS
        END NEWSTAR


你可能感兴趣的:(汇编,案例4加减乘除四则运算)