05 简易计算器
2015-12-14 22:11
423 查看
前言
1 仅仅支持两个操作数一个操作符的计算
2 输入为十进制, 输出为十六进制
参考代码
效果截图 :
1 仅仅支持两个操作数一个操作符的计算
2 输入为十进制, 输出为十六进制
参考代码
assume cs:code, ds:data, ss:stack data segment notice db 'please input a plus/subtract/multiply/divide expression : $ ' ; notice information buffer db 16 ; the buffer to saved the information user inputed, and result show information db 0 db 32 dup (0), ' $ ' operand dw 4 dup (0) ; save the operand and operator and calcute result ; result db 32 dup (0) errInfo db 0aH, 0dH, 'have no operator.... $ ' ; save the error information tmp dw 2 dup (0) ; the temp memory for save offset data ends stack segment db 128 dup (0) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax ; initilization ds, ss lea dx, notice mov ah, 9 int 21H ; output notice information lea dx, buffer mov ah, 10 int 21H ; let user to input mov cl, buffer[1] mov ch, 0 ; get the length of user inputed call getOperator ; get operator, and offset saved in si, and save it into 'operand[1]' ; call getNumValue call getOperand ; get the operand, save it into 'operand', 'operand[2]' call calcuteIt ; to calcute the expression call putResultIntoMemory ; put the information into specified memory lea dx, buffer+2 ; show the result information mov ah, 9 int 21H mov ax, 4c00H ; return to cmd int 21H ; getNumValue proc near ; getNumValueLoop1: ; loop getNumValueLoop1 ; getNumValue endp putResultIntoMemory proc near ; put the result into memory for show push di push bx mov di, cx add di, 2 mov buffer[di], '=' mov bx, operand[6] call calcOneWord pop bx pop di ret putResultIntoMemory endp calcHalfByte proc near ; calc the bl [----just judge lower four bit----]' s corresponding ascii code, save in bl ; push bx ; bl record the data[need to be transfer] push cx ; record the offset to save in exp data segment cmp bl, 9 ja abc ; bl not bigger than 9 ; mov [exp+cx], bl+48 ; 1 ~ 8 add bl, 48 jmp calcHalfByteEnd abc: ; bl bigger than 9 ; mov [exp+cx], bl+87 ; A ~ F add bl, 87 calcHalfByteEnd: pop cx ret calcHalfByte endp calcHalfWord proc ; to calcute two hexadecimal number, number saved in bl, need to push two offset relative exp flag to save data push bx push di push dx push cx ; add sp, 4 ; mov stack pointer to save data offset, why there need just add 2 bit ? it just push ip in stack ? mov dx, bx mov cl, 4 ; calc the upper 4 bit shr bl, cl call calcHalfByte ; pop di mov di, ds:[tmp] ; the segment of tmp must match the left value[cx], use dw to define data mov ds:[buffer+di], bl mov bx, dx ; calc the lower 5 bit and bl, 15 call calcHalfByte ; pop di mov di, ds:[tmp+2] mov ds:[buffer+di], bl ; sub sp, 6 ; mov stack pointer to the real stack top ; why the value in stack changed ??? --2014.07.25 pop cx pop dx pop di pop bx ret calcHalfWord endp calcOneWord proc near ; to calcute two hexadecimal number, number saved in 'bx', 'di' saved the memory offset, push dx push di mov dx, bx mov cl, 8 ; calc the upper 8 bit of bx shr bx, cl inc di mov ds:[tmp], di inc di mov ds:[tmp+2], di call calcHalfWord mov bx, dx ; calc the lower 8 bit of bx mov bh, 0 inc di mov ds:[tmp], di inc di mov ds:[tmp+2], di call calcHalfWord pop di pop dx ret calcOneWord endp calcuteIt proc near ; to calcute the value of expression, and save it to specified memory push bx push ax push dx mov bx, operand[2] cmp bx, 1 jz opePlus2 cmp bx, 2 jz opeSub2 cmp bx, 3 jz opeMul2 cmp bx, 4 jz opeDiv2 jmp calcuteItEnd opePlus2: mov ax, ds:[operand] add ax, operand[4] mov operand[6], ax jmp calcuteItEnd opeSub2: mov ax, ds:[operand] sub ax, operand[4] mov operand[6], ax jmp calcuteItEnd opeMul2: mov ax, ds:[operand] mul operand[4] mov operand[6], ax ; for simple, ignore dx jmp calcuteItEnd opeDiv2: mov ax, ds:[operand] div operand[4] mov operand[6], ax ; jmp calcuteItEnd calcuteItEnd: pop dx pop ax pop bx ret calcuteIt endp getOperand proc near ; to get two operand, and put them into specified meomry push di push si push dx push cx cmp operand[1], 0 jz getOperandOnError ; mov cx, si-2 ; error ; mov di, si-1 mov cx, si sub cx, 2 mov di, si dec di mov al, 1 mov dx, 0 call getOperandValue mov ds:[operand], dx pop cx push cx ; mov cx, dx+1-si ; error ; mov di, dx+1 sub cx, si inc cx mov di, cx add di, si mov al, 1 mov dx, 0 call getOperandValue mov ds:[operand+4], dx jmp getOperandEnd getOperandOnError: ; address flag can't duplicated with others flag call onError getOperandEnd: pop cx pop dx pop si pop di ret getOperand endp getOperandValue proc near ; get operand NumberValue by the number string in memory 1 2 3 -> 123 push di push ax getOperandValueLoop1: mov ah, buffer[di] call getNumValue push ax mul ah add dx, ax pop ax mov ah, 10 mul ah dec di loop getOperandValueLoop1 pop ax pop di ret getOperandValue endp getNumValue proc near ; get NumberValue by ascii cmp ah, 48 jae numFlag1 jmp getNumValueEnd numFlag1: cmp ah, 57 jbe numFlag2 jmp alphaFlag1 numFlag2: sub ah, 48 jmp getNumValueEnd alphaFlag1: cmp ah, 97 jae alphaFlag2 jmp getNumValueEnd alphaFlag2: cmp ah, 102 ja getNumValueEnd sub aH, 87 getNumValueEnd: ret getNumValue endp onError proc near ; deal while error happened push dx push ax lea dx, errInfo mov ah, 9 int 21H pop ax pop dx ret onError endp getOperator proc near ; get the operator in expression, the offset of operator saved in 'si' push cx push bx mov si, 2 getOperatorLoop1: mov bl, buffer[si] call ifIsOperator jc getOperatorEnd inc si loop getOperatorLoop1 getOperatorEnd: pop bx pop cx ret getOperator endp ifIsOperator proc near ; to judge if 'bl' is a operator cmp bl, 43 jz opePlus cmp bl, 45 jz opeSub cmp bl, 42 jz opeMul cmp bl, 47 jz opeDiv jmp ifIsOperatorEnd opePlus: mov operand[2], 1 jmp ifIsOperatorBeforeEnd opeSub: mov operand[2], 2 jmp ifIsOperatorBeforeEnd opeMul: mov operand[2], 3 jmp ifIsOperatorBeforeEnd opeDiv: mov operand[2], 4 jmp ifIsOperatorBeforeEnd ifIsOperatorBeforeEnd: stc ifIsOperatorEnd: ret ifIsOperator endp code ends end start ; made by 970655147 2014.07.27
效果截图 :
相关文章推荐
- iOS开发之MBProgressHUD
- tableau 合计选项
- Python字符串格式符号含义
- 添加窗体控件
- Xmind几个有用的技巧
- Ubuntu下使用GStreamer开发简单的mp3播放器
- AutoCompleteTextView
- android小技巧
- 数据结构与算法——在一定范围内求最少标记点
- C++之可变参数的实现简介
- java开发自定义表单功能类:FormUtil
- DEM提取一定高程值范围像元
- 使用简单jQuery工具来实现表单的验证
- OpenCV中的数据结构
- hibernate(四)ID生成策略
- 02java语法回顾_常用api类之stringbuffer
- Waitkey函数的用法
- Android:菜单随记
- 4-1 简单输出整数
- 红黑树的应用