案例4加减乘除四则运算

来源:互联网 发布:mysql没有可视化界面 编辑:程序博客网 时间:2024/05/24 13:28

这是从网上下载下来的一个计算程序,能实现加、减、乘、除的计算。该程序接受的是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 PTRW_P     EQU WORD PTRD_P     EQU DWORD PTRCODE    SEGMENTASSUME  CS:CODE,DS:CODE        ORG 100H;主程序开始NEWSTAR:        JMP STAR        EVENNUM1    DW 0,0NUM2    DW 0,0NUM3    DW 0,0JGV4    DW 0,0YSF     LABEL WORDYSF1    DB 0YSF2    DB 0JUV     DB 0UV      DB 0;使DS:SI指向第一有效字符OVERS   LABEL NEAR        CLD        PUSH AXOVERS1:        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 SIISYSF1:        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,BPDOUT1:        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 DOUT1DOUT2:        POP AX        ADD AL,'0'        CMP AL,'9'        JBE DOUT3        ADD AL,'A'-'9'-1DOUT3:        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,DXDATE1:        MOV DI,AX        LODSB        CMP AL,'0'        JB DATE7        CMP AL,'9'        JA DATE6DATE2:        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 DATE4DATE3:        ADD DI,BX        ADC DX,BPDATE4:        ADD AX,DI        ADC DX,0        JMP DATE1DATE5:        ADD AL,9        JMP DATE2DATE6:        JCXZ DATE7        CMP AL,'A'        JB DATE7        CMP AL,'F'        JBE DATE5        CMP AL,'a'        JB DATE7        CMP AL,'f'        JBE DATE5DATE7:        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 JSJJ2JSJJ1:        ADD NUM1,AX        ADC NUM1+2,DXJSJJ2:        RET;数据1与数据2根据YSF1进行乘除运算JSII1   LABEL NEAR        MOV BX,OFFSET NUM1        JMP SHORT JSII2_1;数据2与数据3根据YSF2进行乘除运算JSII2   LABEL NEAR        MOV BX,OFFSET NUM2JSII2_1:        DB 66H        MOV AX,[BX]        DB 66H        MOV CX,[BX+4]        CMP YSF2,'*'        JNZ JSII2_2        DB 66H        IMUL CX        JMP SHORT JSII2_3JSII2_2:        DB 66H        CWD        DB 66H        IDIV CX        CMP YSF2,'/'        JZ JSII2_3        DB 66H        XCHG DX,AXJSII2_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,16XUJG0:        TEST DX,8000H        JZ XUJG1        CMP UV,10        JZ XUJG2        CALL DOUTXUJG2:        NOT AX        NOT DX        ADD AX,1        ADC DX,0        PUSH AX        CMP UV,10        JZ XUJG3        MOV AL,' '        CALL DISP        MOV AL,'('        CALL DISPXUJG3:        MOV AL,'-'        CALL DISP        POP AX        CMP UV,10        JZ XUJG1        CALL DOUT        MOV AL,')'        CALL DISP        RETXUJG1:        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        RETLOADATE1:        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,DXSZYS1:        XOR AX,AX       ;数据2清零        MOV NUM2,AX        MOV NUM2+2,AX        CALL ISYSF      ;下个是运算符?        JZ SZYS3        JNZ SZYS6SZYS2:        PUSH AX        MOV AX,JGV4     ;将结果作为数据1        MOV NUM1,AX        MOV AX,JGV4+2        MOV NUM1+2,AX        POP AXSZYS3:        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,DXSZYS4_1:        CALL ISYSF        JNZ SZYS6        CALL ISJJ       ;运算符2是加减运算?        JNZ SZYS5       ;不是转        PUSH AX        CALL JSJJ       ;数据1与数据2根据YSF1进行加减运算        POP AX          ;    结果保存在数据1中        MOV YSF1,AL     ;保存新的运算符        JMP SZYS4SZYS5:        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 SZYS9SZYS7:        CALL JSJG        CMP JUV,0        JZ SZYS8        DEC JUV        POP YSF        POP NUM2+2        POP NUM2        POP NUM1+2        POP NUM1        RETSZYS8:        CMP CL,')'        JZ SZYS10        MOV JGV4,AX        MOV JGV4+2,DX        JNZ SZYS12SZYS9:        CMP AL,')'        JNZ SZYS11        INC SI        JMP SZYS7SZYS10:        MOV NUM1,AX        MOV NUM1+2,DX        JMP SZYS1SZYS11:        STC        RETSZYS12:        CLC        RET;数制处理UVIL    LABEL NEAR        PUSH SIUVIL1:        LODSB        CMP AL,' '        JZ UVIL2        CMP AL,9        JZ UVIL2        CMP AL,13        JZ UVIL4        JNZ UVIL1UVIL2:        MOV BX,SI        CALL OVERS        JZ UVIL3        LODSW        CALL OVERS        POP SI        JNZ SZYS11        CMP AX,'01'        JNZ SZYS11        PUSH SI        MOV UV,10UVIL3:        MOV AL,13        MOV [BX-1],ALUVIL4:        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        RETSTAR:        MOV SI,81H        CLD        CALL OVERS        JNZ STAR1STAR0:        MOV DX,OFFSET MESS1        JMP STAR4STAR1:        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 MESS3STAR4:        MOV AH,9        INT 21H        INT 20HSAVESP  DW 0MESS1   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


1 0