【汇编大作业】设计计算器,可以实现2进制,8进制,10进制,16进制之间的输入计算

这是一个基于DOS的计算器程序,支持二进制、八进制、十进制和十六进制的输入,以十进制输出结果。程序首先提示用户输入数字和操作符,然后通过辗转相除法将输入转换为十进制数,进行计算。若输入格式有b(二进制)、o(八进制)、h(十六进制)后缀,程序会按相应格式解析。程序还提供了除0异常处理。
摘要由CSDN通过智能技术生成
DATAS SEGMENT
BUF1 DB 16
     DB  0
     DB 16 DUP(0)
BUF2 DB 16
     DB  0
     DB 16 DUP(0)
NUM2 Db ?
NUM  DW  ?
NUM1 DW ?
ANSWER DW 0
Signflag db ?
prompt1 db 'Enter the first number: $'
prompt2 db 'Enter the operator: $'
prompt3 db 'Enter the second number: $'
prompt4 db 'Result is: $'
prompt5 db 'The default input format for this calculator is binary, and the output format is decimal. You can indicate the input format by adding a suffix: b for binary,o for octal, and h for hexadecimal, after the input number.'
newline db  0Ah, 0Dh, '$'
DATAS ENDS
   
STACKS SEGMENT PARA STACK
   DW 30H DUP(0)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX

    mov ah, 09h
    lea dx, prompt5
    int 21h

    mov ah, 09h
    lea dx, prompt1
    int 21h
    CALL STOIA

    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt2
    int 21h
    MOV AH,1
    INT 21H
    mov Signflag, al


    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt3
    int 21h
    CALL STOIB
 

    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt4
    int 21h
    CALL OUTPT
    MOV AH,4CH
    INT 21H
STOIA PROC          ;辗转相除法 将输入的十进制数转存到num中 
   
             MOV AH,0AH
             LEA DX,BUF1
             INT 21H          ;读入数据     

	MOV DX,BUF1
	MOV NUM,0
    Mov bx,10
	MOV AX,0
   
 MOV SI,OFFSET BUF1+1
    mov si,BUF1[si];
    and si,00ffh
    inc si
    mov al,BUF1[si]
    mov NUM2,al
    cmp al,62h
   jz  isBinary1
    cmp al,6Fh
   jz  isOctal1
    cmp al,68h
   jz isHexa1
   cmp al,64h
   jz isDeci1

isBinary1:
    MOV BX,2
    jmp goto1
isOctal1:
    MOV BX,8
    jmp goto1 
isHexa1:
    MOV BX,16
    jmp goto1
isDeci1:
    MOV BX,10
goto1 :

MOV SI,OFFSET BUF1+2
MOV AX,0
LOP:
    MOV AL,BUF1[SI]
    CMP AL,0DH
    JE  FINAL
    CMP AL,62H
    JE  FINAL
    CMP AL,6FH
    JE  FINAL
    CMP AL,68H
    JE  FINAL
    CMP AL,64H
    JE  FINAL
    SUB AL,30H
    CMP NUM,0
    JE  DO_DEAL 
    PUSH AX
    MOV AX,NUM
    MUL BX 
    MOV  NUM,AX  
    POP AX
DO_DEAL:
    ADD NUM,AX
    MOV AX,0
    INC SI
    JMP LOP
FINAL:    
RET
STOIA ENDP
STOIB PROC          ;辗转相除法 将输入的十进制数转存到num中 
   
    LEA DX,BUF2
    MOV AH,0AH
    INT 21H          ;读入数据     

	MOV DX,BUF2
	MOV SI,OFFSET BUF2+2
    Mov bx,10
	MOV NUM1,0
	MOV AX,0

    MOV SI,OFFSET BUF2+1
    mov si,BUF1[si];
    and si,00ffh
     inc si
    mov al,BUF1[si]
    cmp al,62h
   jz  isBinary2
    cmp al,6Fh
   jz  isOctal2
    cmp al,68h
   jz isHexa2
   cmp al,64h
   jz isDeci2

isBinary2:
    MOV BX,2
    jmp goto2 
isOctal2:
    MOV BX,8
    jmp goto2 
isHexa2:
    MOV BX,16
    jmp goto2 
isDeci2:
    MOV BX,10
goto2 :
	MOV SI,OFFSET BUF2+2
LOP1:
    MOV AL,BUF1[SI]
    CMP AL,0DH
    JE  FINAL1
    CMP AL,62H
    JE  FINAL1
    CMP AL,6FH
    JE  FINAL1
    CMP AL,68H
    JE  FINAL1
    CMP AL,64H
    JE  FINAL1
    SUB AL,30H
    CMP NUM1,0
    JE  DO_DEAL1 
    PUSH AX
    MOV AX,NUM1
    MUL BX 
    MOV  NUM1,AX  
    POP AX
DO_DEAL1:
    ADD NUM1,AX
    MOV AX,0
    INC SI
    JMP LOP1
FINAL1:    
RET
STOIB ENDP

OUTPT PROC  

MOV AL,Signflag
CMP AL,'+'
JZ MYADD
CMP AL,'-'
JZ MYSUB
CMP AL,'*'
JZ MYMUL
CMP AL,'/'
JZ MYDIV


MYADD:
     mov  ax,NUM
     add  ax,NUM1
     mov  answer ,ax
   jmp goon
MYSUB:
     mov  ax,NUM
     sub  ax,NUM1
     mov  answer ,ax
   jmp goon
MYMUL:
     mov ah,0
     mov  al,byte ptr NUM
     mul  byte ptr NUM1
     mov  answer ,ax
   jmp goon
MYDIV:
     mov ah,0
     mov  al,byte ptr NUM
     div  byte ptr NUM1
     mov  byte ptr answer , al
goon:
    mov ax,ANSWER
    push ax
    mov al,byte ptr ANSWER
    mov ah, 0
    mov bx, 10
    mov cx, 0
    
     count_digits:
        mov ah,0
        mov al,byte ptr ANSWER
        inc cx ; 增加计数器
        div bl ; 除以10
        mov byte ptr ANSWER ,al
        cmp al,0 ; 判断商是否为0
    jnz count_digits ; 如果不为0,继续循环


   pop ax
   mov ANSWER,ax
     loop_start:
        ; 获取缓冲区的内容
        mov al,byte ptr ANSWER
        
        ; 除法运算
        xor ah,ah ; 清除高位寄存器
        call power_of_10
        div bl ; 除以BX寄存器中的数据
        mov byte ptr answer,ah  ; 更新缓冲区的内容为余数,即下一次循环的被除数
        ; 显示商
        mov dl,al ; 存储要显示的字符
        add dl,30h
        mov ah,2h ; 显示字符的功能号
        int 21h ; 调用DOS中断显示字符
           
        ; 循环次数减1
        loop loop_start

OUTPT ENDP
power_of_10 proc
    push ax ; 保存寄存器现场
    push cx    
    mov ax, 1 ; 初始化结果为1
    mov bx, 10 ; 初始化底数为10
     
    dec cx
    power_loop:
        cmp cx, 0 ; 检查n是否为0
        je power_end ; 如果是,跳出循环
        
        mul bx ; 结果乘以底数
        dec cx ; n减1
        
        jmp power_loop ; 继续循环
    
    power_end:
    mov bx, ax ; 将结果保存到BX寄存器
    
    pop cx
    pop ax ; 恢复寄存器现场
    ret
power_of_10 endp
CODES ENDS
END START

这个计算器默认的是2进制的输入,10进制的输出,你可以在输入时在末尾显示的输入b二进制,d十进制,o八进制,h十六进制,例如输入 10b ,13h

由于时间限制本计算器有些异常条件未进行处理,但本计算器保留了较好的接口,方便读者去自行扩展

例如以下就是案例

对该计算器改为了10进制的默认输入,并加上了除0异常报错

DATAS SEGMENT
BUF1 DB 16
     DB  0
     DB 16 DUP(0)
BUF2 DB 16
     DB  0
     DB 16 DUP(0)
NUM2 Db ?
NUM  DW  ?
NUM1 DW ?
ANSWER DW 0
Signflag db ?
prompt1 db 'Enter the first number: $'
prompt2 db 'Enter the operator: $'
prompt3 db 'Enter the second number: $'
prompt4 db 'Result is: $'
prompt5 db 'The default input format for this calculator is decimal , and the output format is decimal. You can indicate the input format by adding a suffix: b for binary,o for octal, and h for hexadecimal, after the input number.$'
prompt6 db 'division by zero$'
newline db  0Ah, 0Dh, '$'
DATAS ENDS
   
STACKS SEGMENT PARA STACK
   DW 30H DUP(0)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX

    mov ah, 09h
    lea dx, prompt5
    int 21h

    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt1
    int 21h
    CALL STOIA

    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt2
    int 21h
    MOV AH,1
    INT 21H
    mov Signflag, al


    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt3
    int 21h
    CALL STOIB
 

    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt4
    int 21h
    CALL OUTPT

  
    MOV AH,4CH
    INT 21H
STOIA PROC          ;辗转相除法 将输入的十进制数转存到num中 
   
             MOV AH,0AH
             LEA DX,BUF1
             INT 21H          ;读入数据     

	MOV DX,BUF1
	MOV NUM,0
    Mov bx,10
	MOV AX,0
   
 MOV SI,OFFSET BUF1+1
    mov si,BUF1[si];
    and si,00ffh
    inc si
    mov al,BUF1[si]
    mov NUM2,al
    cmp al,62h
   jz  isBinary1
    cmp al,6Fh
   jz  isOctal1
    cmp al,68h
   jz isHexa1
   cmp al,64h
   jz isDeci1


isDeci1:
    MOV BX,10
    jmp goto1
isOctal1:
    MOV BX,8
    jmp goto1 
isHexa1:
    MOV BX,16
    jmp goto1
isBinary1:
    MOV BX,10
goto1 :

MOV SI,OFFSET BUF1+2
MOV AX,0
LOP:
    MOV AL,BUF1[SI]
    CMP AL,0DH
    JE  FINAL
    CMP AL,62H
    JE  FINAL
    CMP AL,6FH
    JE  FINAL
    CMP AL,68H
    JE  FINAL
    CMP AL,64H
    JE  FINAL
    SUB AL,30H
    CMP NUM,0
    JE  DO_DEAL 
    PUSH AX
    MOV AX,NUM
    MUL BX 
    MOV  NUM,AX  
    POP AX
DO_DEAL:
    ADD NUM,AX
    MOV AX,0
    INC SI
    JMP LOP
FINAL:    
RET
STOIA ENDP
STOIB PROC          ;辗转相除法 将输入的十进制数转存到num中 
   
    LEA DX,BUF2
    MOV AH,0AH
    INT 21H          ;读入数据     

	MOV DX,BUF2
	MOV SI,OFFSET BUF2+2
    Mov bx,10
	MOV NUM1,0
	MOV AX,0

    MOV SI,OFFSET BUF2+1
    mov si,BUF1[si];
    and si,00ffh
     inc si
    mov al,BUF1[si]
    cmp al,62h
   jz  isBinary2
    cmp al,6Fh
   jz  isOctal2
    cmp al,68h
   jz isHexa2
   cmp al,64h
   jz isDeci2


isDeci2:
    MOV BX,10
    jmp goto2 
isOctal2:
    MOV BX,8
    jmp goto2 
isHexa2:
    MOV BX,16
    jmp goto2 
isBinary2:
    MOV BX,2
goto2 :
	MOV SI,OFFSET BUF2+2
LOP1:
    MOV AL,BUF1[SI]
    CMP AL,0DH
    JE  FINAL1
    CMP AL,62H
    JE  FINAL1
    CMP AL,6FH
    JE  FINAL1
    CMP AL,68H
    JE  FINAL1
    CMP AL,64H
    JE  FINAL1
    SUB AL,30H
    CMP NUM1,0
    JE  DO_DEAL1 
    PUSH AX
    MOV AX,NUM1
    MUL BX 
    MOV  NUM1,AX  
    POP AX
DO_DEAL1:
    ADD NUM1,AX
    MOV AX,0
    INC SI
    JMP LOP1
FINAL1:    
RET
STOIB ENDP

OUTPT PROC  

MOV AL,Signflag
CMP AL,'+'
JZ MYADD
CMP AL,'-'
JZ MYSUB
CMP AL,'*'
JZ MYMUL
CMP AL,'/'
JZ MYDIV


MYADD:
     mov  ax,NUM
     add  ax,NUM1
     mov  answer ,ax
   jmp goon
MYSUB:
     mov  ax,NUM
     sub  ax,NUM1
     mov  answer ,ax
   jmp goon
MYMUL:
     mov ah,0
     mov  al,byte ptr NUM
     mul  byte ptr NUM1
     mov  answer ,ax
   jmp goon
MYDIV:
     mov ah,0
     mov  bl,byte ptr NUM
     mov  al,byte ptr NUM1
     cmp al,0
     jz unleg0
     mov  al,bl
     div  byte ptr NUM1
     mov  byte ptr answer , al
goon:
    mov ax,ANSWER
    push ax
    mov al,byte ptr ANSWER
    mov ah, 0
    mov bx, 10
    mov cx, 0
    
     count_digits:
        mov ah,0
        mov al,byte ptr ANSWER
        inc cx ; 增加计数器
        div bl ; 除以10
        mov byte ptr ANSWER ,al
        cmp al,0 ; 判断商是否为0
    jnz count_digits ; 如果不为0,继续循环


   pop ax
   mov ANSWER,ax
     loop_start:
        ; 获取缓冲区的内容
        mov al,byte ptr ANSWER
        
        ; 除法运算
        xor ah,ah ; 清除高位寄存器
        call power_of_10
        div bl ; 除以BX寄存器中的数据
        mov byte ptr answer,ah  ; 更新缓冲区的内容为余数,即下一次循环的被除数
        ; 显示商
        mov dl,al ; 存储要显示的字符
        add dl,30h
        mov ah,2h ; 显示字符的功能号
        int 21h ; 调用DOS中断显示字符
           
        ; 循环次数减1
        loop loop_start
        jmp nounleg0
unleg0:
     
    lea dx, newline
    mov ah, 09h
    int 21h
    mov ah, 09h
    lea dx, prompt6
    int 21h
nounleg0:
OUTPT ENDP
power_of_10 proc
    push ax ; 保存寄存器现场
    push cx    
    mov ax, 1 ; 初始化结果为1
    mov bx, 10 ; 初始化底数为10
     
    dec cx
    power_loop:
        cmp cx, 0 ; 检查n是否为0
        je power_end ; 如果是,跳出循环
        
        mul bx ; 结果乘以底数
        dec cx ; n减1
        
        jmp power_loop ; 继续循环
    
    power_end:
    mov bx, ax ; 将结果保存到BX寄存器
    
    pop cx
    pop ax ; 恢复寄存器现场
    ret
power_of_10 endp
CODES ENDS
END START

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值