加减乘除四则运算

2008-10-22     作者:        编辑:齐瑞瑞   点击进入论坛

  程序功能:

  此程序能实现加、减、乘、除的计算。程序接受的是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

  程序清单:

  ;js.asm

  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 [10]',13,10,'$'

  MESS2 DB 'Error in expression !$'

  MESS3 DB 13,10,'$'

  CODE ENDS

  END NEWSTAR

寻找产品:
姓       名: 电   话:
公       司: E-mail:
描       述: