⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e3.asm

📁 汇编实验,用汇编语言实现一些简单操作,包括文件读写
💻 ASM
字号:
        DATA  SEGMENT
        CRLF  DB        0AH,0DH,"$" ;此处输入数据段代码
   INPUTHINT  DB        0AH,0DH,"input the expression: ",'$'
           ERRORINPUTMSG  DB        0AH,0DH,"ILLEAGLE INPUT.",0AH,0DH,'$'
        ERRORTWOOPERATOR  DB        0AH,0DH,"THERE ARE TWO OPERATOR ADJACENT!",0AH,0DH,'$'
          ERRORFIRSTCHAR  DB        0AH,0DH,"THE FIRST CHARACTER MUST BE '(','+','-',OR A DIGIT.",0AH,0DH,'$'
     OPSTACK  DB        256 DUP(0)  ; operator stack
       INFIX  DB        512 DUP(0)  ; infix expression stack
      CHLAST  DB        -1          ; the character that is reat last time.
   DATASTACK  DW        256 DUP(0)  ; data stack
        DATA  ENDS

        CODE  SEGMENT
              ASSUME    CS:CODE, DS:DATA
        MAIN  PROC      FAR
              MOV       AX, DATA
              MOV       DS, AX
              MOV       AH, 9
              LEA       DX, INPUTHINT
              INT       21H

              CALL      INPUT
              CALL      CALCULATE
              CALL      PRINT

              MOV       AH, 4CH
              INT       21H
       INPUT  PROC      NEAR
              PUSH      AX
              PUSH      BX
              LEA       BX, INFIX
  INPUT_EXP:  MOV       AH, 1
              INT       21H
               
              CMP       AL, 13      ;huiche
              JE        EXIT_INPUT
             ;   call inputCheck ;is the character illegal?
              MOV       [BX], AL
              INC       BX          ;infix as stack
              JMP       INPUT_EXP
 EXIT_INPUT:  MOV       BYTE PTR [BX], '='
              POP       BX
              POP       AX
              RET
       INPUT  ENDP
   CALCULATE  PROC      NEAR        ;计算中缀表达式函数
              PUSH      AX          ; ax -- 计算结果累加器
              PUSH      CX          ; ch -- 运算符栈顶元素, compute 函数的入口参数之一
              PUSH      DX          ; cl -- 当前从中缀表达式中读入的元素
              PUSH      BX          ; bx -- opStack 栈顶指针
              PUSH      DI          ; di -- dataStack 栈顶指针
              PUSH      SI          ; si -- 中缀表达式下标
              MOV       BX, -1
              MOV       SI, -1
              MOV       DI, -2
    ANALYZE:  INC       SI          ;读入待分析字符, 存入在CL寄存器中
              MOV       CL, BYTE PTR INFIX[SI]
              CMP       CL, '='
              JE        CASE_EXIT
              CMP       CL, '('
              JE        CASE_LEFT
              CMP       CL, ')'
              JE        CASE_RIGHT
              CMP       CL, '+'
              JE        CASE_ADD
              CMP       CL, '-'
              JE        CASE_SUB
               
              JMP       CASE_DATA
  CASE_EXIT:  JMP       EXIT_CALCULATE
  CASE_LEFT:  JMP       LEFT
 CASE_RIGHT:  JMP       RIGHT
   CASE_ADD:  JMP       ADDSUB
   CASE_SUB:  JMP       ADDSUB

  CASE_DATA:  JMP       READ_DATA
       LEFT:  INC       BX
              MOV       BYTE PTR OPSTACK[BX], '('
              MOV       CHLAST, '('
              JMP       ANALYZE
      RIGHT:  MOV       CL, BYTE PTR OPSTACK[BX]
              DEC       BX
              CMP       CL, '('
              JE        ANALYZE
              MOV       CH, CL
              CALL      COMPUTE
              JMP       RIGHT
     ADDSUB:  CMP       CHLAST, -1
              JZ        PUSH_DATA_0
              CMP       CHLAST, '('
              JZ        PUSH_DATA_0
              CMP       CHLAST, '+'
              JZ        ERRTWOOPERATOR
              CMP       CHLAST, '-'
              JZ        ERRTWOOPERATOR
      
              JMP       PUSH_CL
            PUSH_DATA_0:  ADD       DI, 2
              MOV       WORD PTR DATASTACK[DI], 0
    PUSH_CL:  CMP       BX, -1      ; is opStack empty ?
              JZ        PUSH_CL_DIRECT
              MOV       CH, BYTE PTR OPSTACK[BX]
              CMP       CH, '('     ; the top of opStack is '(' ?
              JZ        PUSH_CL_DIRECT
              MOV       BYTE PTR OPSTACK[BX], CL
              CALL      COMPUTE
              MOV       CHLAST, CL
              JMP       ANALYZE
         PUSH_CL_DIRECT:  INC       BX
              MOV       BYTE PTR OPSTACK[BX], CL
              MOV       CHLAST, CL
              JMP       ANALYZE
         ERRTWOOPERATOR:  LEA       DX, ERRORTWOOPERATOR
              MOV       AH, 9
              INT       21H
              MOV       AH, 4CH
              INT       21H
     MULDIV:  CMP       CHLAST, -1
              JZ        ERRFIRSTCHAR
              CMP       CHLAST, '+'
              JZ        ERRTWOOPERATOR
              CMP       CHLAST, '-'
              JZ        ERRTWOOPERATOR
       
              CMP       CHLAST, '('
              JZ        ERRFIRSTCHAR
              JMP       MULDIV_X
           ERRFIRSTCHAR:  LEA       DX, ERRORFIRSTCHAR
              MOV       AH, 9
              INT       21H
              MOV       AH, 4CH
              INT       21H
   MULDIV_X:  CMP       BX, -1      ; is stack empty ?
              JE        PUSH_MULDIV
              MOV       CH, BYTE PTR OPSTACK[BX]            ;peek the element on the top
              CMP       CH, '*'
              JE        COMP_MULDIV
              CMP       CH, '/'
              JE        COMP_MULDIV
              JMP       PUSH_MULDIV ; the top is neither '*' nor '/', push cl directly
            COMP_MULDIV:  MOV       BYTE PTR OPSTACK[BX], CL            ; replace
              CALL      COMPUTE
              MOV       CHLAST, CL
              JMP       ANALYZE
            PUSH_MULDIV:  INC       BX
              MOV       BYTE PTR OPSTACK[BX], CL
              MOV       CHLAST, CL
              JMP       ANALYZE
  READ_DATA:  XOR       AX, AX
       READ:  ADD       AX, AX      ; use add, never use adc
              MOV       DX, AX
              ADD       AX, AX
              ADD       AX, AX
              ADD       AX, DX
              AND       CX, 0FH
              ADD       AX, CX
              INC       SI
              MOV       CL, BYTE PTR INFIX[SI]
              CMP       CL, '0'
              JC        FINISH_READ
              CMP       CL, 3AH
              JNC       FINISH_READ
              JMP       READ
            FINISH_READ:  ADD       DI, 2
              MOV       WORD PTR DATASTACK[DI], AX
              DEC       SI
              MOV       CHLAST, '2'
              JMP       ANALYZE
     PRE_EXIT_CALCULATE:  MOV       CH, BYTE PTR OPSTACK[BX]
              DEC       BX
              CALL      COMPUTE     ; no jump, just fall down
         EXIT_CALCULATE:  CMP       BX, -1      ; is operator stack empty ?
              JNE       PRE_EXIT_CALCULATE
              POP       SI
              POP       DI
              POP       BX
              POP       DX
              POP       CX
              POP       AX
              RET
   CALCULATE  ENDP
     COMPUTE  PROC      NEAR        ;用来计算每一步结果,两个入参:ch-运算符,di-数据栈顶指针
              PUSH      AX
              PUSH      DX
              CMP       DI, 2
              JC        EXIT_COMPUTE
              MOV       DX, WORD PTR DATASTACK[DI]          ; the second operator
              SUB       DI, 2
              MOV       AX, WORD PTR DATASTACK[DI]          ; the first operator
              SUB       DI, 2
              AND       AX, AX      ; set cf = 0
              CMP       CH, '+'
              JE        ADDF
              CMP       CH, '-'
              JE        SUBF
     
       ADDF:  ADC       AX, DX
              JMP       FINISH_C
       SUBF:  SBB       AX, DX
              JMP       FINISH_C

   FINISH_C:  ADD       DI, 2
              MOV       WORD PTR DATASTACK[DI], AX
           EXIT_COMPUTE:  POP       DX
              POP       AX
              RET
     COMPUTE  ENDP
       PRINT  PROC      NEAR        ;输出结果函数
              LEA       DX,CRLF
              MOV       AH,9
              INT       21H
              PUSH      AX
              PUSH      CX
              PUSH      DX
              MOV       CX, WORD PTR DATASTACK
              TEST      CX, 8000H   ;是否为负数
              JNZ       NEGATIVE
      BEGIN:  CMP       CX, 10000
              JNC       TEN_THOUSAND
              CMP       CX, 1000
              JNC       THOUSAND
              CMP       CX, 100
              JNC       HANDRED
              CMP       CX, 10
              JNC       TEN
              JMP       REMAINS
   NEGATIVE:  MOV       DL, '-'
              MOV       AH, 2
              INT       21H
              NEG       CX
              JMP       BEGIN
           TEN_THOUSAND:  MOV       DL, -1
         AA:  SUB       CX, 10000
              INC       DL
              JNC       AA
              ADD       CX, 10000
              OR        DL, 30H
              MOV       AH, 2
              INT       21H
   THOUSAND:  MOV       DL, -1
         BB:  SUB       CX, 1000
              INC       DL
              JNC       BB
              ADD       CX, 1000
              OR        DL, 30H
              MOV       AH, 2
              INT       21H
    HANDRED:  MOV       DL, -1
         CC:  SUB       CX, 100
              INC       DL
              JNC       CC
              ADD       CX, 100
              OR        DL, 30H
              MOV       AH, 2
              INT       21H
        TEN:  MOV       DL, -1
        DDD:  SUB       CX, 10
              INC       DL
              JNC       DDD
              ADD       CX, 10
              OR        DL, 30H
              MOV       AH, 2
              INT       21H
    REMAINS:  MOV       DL, CL
              OR        DL, 30H
              MOV       AH, 2
              INT       21H
                
 EXIT_PRINT:  POP       DX
              POP       CX
              POP       AX
              RET
       PRINT  ENDP

        MAIN  ENDP
        CODE  ENDS
              END       MAIN

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -