开学第一周完成的汇编计算器:前后一共写了很多版本,下面是俩个版本:
by hfut 叶泽坤 冯弘承 许金龙 宋彬彬。
基础功能完善版:
stack segment stack
db 1024 dup(?)
stack ends
data segment
LedMap db 0c0h,0f9h,0a4h,0b0h,099h,092h,082h,0f8h ;0 1 2 3 4.....
db 080h,090h,088h,083h,0c6h,0a1h,086h,08eh
KeyTable db 07h,04h,08h,05h,09h,06h,0ah,0bh ;键码定义
db 01h,00h,02h,0fh,03h,0eh,0ch,0dh
bit dw 0h
stack_sign db 0ffh, 100 dup(?) ;符号栈
stack_numb dw 0ffffh, 100 dup(?) ;操作数栈
OUTSEG equ 0ffdch ;段控制口
OUTBIT equ 0ffddh ;位控制口/键扫口
IN_KEY equ 0ffdeh ;键盘读入口
TEN db 10
LedBuf db 00h, 00h, 00h, 00h, 00h, 00h ;显示缓冲
data ends
code segment'code'
assume cs:code,ds:data,ss:stack
org 1000h
Start:
mov LedMap+0,0c0h ;初始化工作
mov LedMap+1,0f9h
mov LedMap+2,0a4h
mov LedMap+3,0b0h
mov LedMap+4,099h
mov LedMap+5,092h
mov LedMap+6,082h
mov LedMap+7,0f8h
mov LedMap+8,080h
mov LedMap+9,090h
mov LedMap+10,088h
mov LedMap+11,083h
mov LedMap+12,0c6h
mov LedMap+13,0a1h
mov LedMap+14,086h
mov LedMap+15,08eh
mov KeyTable+0, 07h
mov KeyTable+1, 04h
mov KeyTable+2, 08h
mov KeyTable+3, 05h
mov KeyTable+4, 09h
mov KeyTable+5, 06h
mov KeyTable+6, 0ah
mov KeyTable+7, 0bh
mov KeyTable+8, 01h
mov KeyTable+9, 00h
mov KeyTable+10, 02h
mov KeyTable+11, 0fh
mov KeyTable+12, 03h
mov KeyTable+13, 0eh
mov KeyTable+14, 0ch
mov KeyTable+15, 0dh
mov stack_sign,0ffh;
mov stack_numb,0ffffh;
mov TEN,10
mov ch,0ffh;
call get0
ss1:
mov bl,ch; 前一个符号
call show; 显示灯
mov al,20h;
call getkey; 获得键
cmp al,20h; 是否有键按下
je ss1; 若无键按下,重新显示
and al,0fh ;高位清零!
call myDelay ;这段时间应该等于手离开键盘的时间
mov ch,al; 保存前一个符号
cmp al,10
jnb next0 ;若是数字:
cmp bl,10
jb go1
call clearbuf;
cmp dx,0 ;若是0,则buff改为0先
jne go1
call clearbuf;
go1:
call renew_led; 更新显示
inc bit ;位数+1
mov bh,al ; 乘以10加个位法
mov ax,dx ;
mul TEN ;
add al,bh ;
adc ah,0 ;
mov dx,ax ; 中间结果暂存与dx
jmp ss1;
next0: ;若是符号
cmp bl,10
jnb go0 ;之前的是符号就跳
call mypush_numb ;先将之前的数字入栈
go0:
mov dx,0;
cmp al,0fh ;是否=
jne go3
go4: ; 是的话
cmp byte ptr stack_sign[si],0ffh ; 是的话,一直爆栈,是否栈底
jne go11
call get_ans ; 是栈底,显示结果结束。
jmp ss1
go11:
call calcu
jmp go4;
go3:
cmp al,0ch ;是否复位
jne go5
call get0;
jmp ss1;
go5:
cmp al,0eh; ;是否括号
jne go2
cmp bl,0feh;
je go6
cmp bl,10 ;是否左括号 (符号后面必是左括号)
jnb left
go6:
mov ch,0feh;
cmp byte ptr stack_sign[si],0eh; ;若是右括号,是否遇到左括号
jne go12
call mypop_sign ;遇到左括号,出栈之
jmp ss1
go12:
call calcu
jmp go6
left:
call mypush_sign ;左括号入站
jmp ss1
go2:
cmp byte ptr stack_sign[si],0eh ;否则必是运算符号,比较优先级
jne go7