assume cs:code, ds:data, ss:stack data segment notice db 'the random expression is : $' ; the notice exp db 10 dup (0) ; the memory to save calcute expression db ' $ ' ; the finish symbol operand dw 3 dup (0) ; save the first operand, operator and the second operand tmp dw 5 dup (0) ; temp memory data ends stack segment ; stack memory db 128 dup (0) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax lea dx, notice ; show the notice sentence mov ah, 9 int 21H call getRandomNunber ; get the first operator mov ds:[operand], bx ; mov ds:[operand], 2424H ; mov ax, 1 ; push ax ; mov ax, 0 ; push ax mov ds:[tmp], 0000H mov ds:[tmp+2], 0001H ; warnning there need to be notified !!!!!!!! call calcHalfWord call getRandomNunber ; get the operator, and write it to memory mov ds:[tmp], 0002H call getOperator call sleep ; sleep for 1000 millis, to get the second random number call getRandomNunber ; get the second operand mov ds:[operand+4], bx mov ds:[tmp], 0003H mov ds:[tmp+2], 0004H call calcHalfWord mov ds:[exp+5], '=' ; write the '=' to memory call getResult ; calc the result, and save to 'bx' register call calcOneWord ; add sp, 4 ; return sp to real offset ; mov ds:[exp+8], '$' lea dx, exp ; show the calcute expression mov ah, 9 int 21H mov ax, 4c00H ; exit to cmd int 21H sleep proc near ; but this is not random number ??? the second number could be calcuted.... push cx push bx mov cx, 0ffffH sleepStart: push cx mov cx, 00fffH sleepSecond: mov bx, 0001H loop sleepSecond pop cx loop sleepStart pop bx pop cx ret sleep endp getResult proc near ; get the calcute result push ax mov bx, ds:[operand+2] cmp bx, 0 jz opePlus2 cmp bx, 1 jz opeSub2 cmp bx, 2 jz opeMul2 cmp bx, 3 jz opeDiv2 opePlus2: mov bx, ds:[operand] add bx, ds:[operand+4] jmp getResultEnd opeSub2: mov bx, ds:[operand] sub bx, ds:[operand+4] jmp getResultEnd opeMul2: mov ax, ds:[operand] mov bx, ds:[operand+4] mul bl mov bx, ax jmp getResultEnd opeDiv2: mov ax, ds:[operand] mov bx, ds:[operand+4] div bl mov ah, 0 ; clear the remained number mov bx, ax jmp getResultEnd getResultEnd: pop ax ret getResult endp getOperator proc near ; in this program, get operator could be executed at the last push di mov di, ds:[tmp] and bx, 3 ; jmp opePlus ; this is for debug cmp bx, 0 jz opePlus cmp bx, 1 jz opeSub cmp bx, 2 jz opeMul cmp bx, 3 jz opeDiv opePlus: mov ds:[operand+2], 0 mov ds:[exp+di], '+' jmp getOperatorEnd opeSub: mov ds:[operand+2], 1 mov ds:[exp+di], '-' jmp getOperatorEnd opeMul: mov ds:[operand+2], 2 mov ds:[exp+di], '*' jmp getOperatorEnd opeDiv: mov ds:[operand+2], 3 mov ds:[exp+di], '/' jmp getOperatorEnd getOperatorEnd: pop di ret getOperator 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:[exp+di], bl mov bx, dx ; calc the lower 5 bit and bl, 15 call calcHalfByte ; pop di mov di, ds:[tmp+2] mov ds:[exp+di], bl ; sub sp, 6 ; mov stack pointer to the real stack top ; why the value in stack changed ??? --2014.07.25 ; pop di ; pop bx pop cx pop dx ret calcHalfWord endp calcOneWord proc near ; to calcute two hexadecimal number, number saved in bx, need to push two offset relative exp flag to save data push dx mov dx, bx mov cl, 8 ; calc the upper 8 bit of bx shr bx, cl mov ds:[tmp], 0006H mov ds:[tmp+2], 0007H call calcHalfWord mov bx, dx ; calc the lower 8 bit of bx mov bh, 0 mov ds:[tmp], 0008H mov ds:[tmp+2], 0009H call calcHalfWord pop dx ret calcOneWord endp getRandomNunber proc near ; the process to get a random number, save to bl push ax push dx sti mov ah, 0 int 1AH ; the interrupt that read the clock 'click' number while ah equal 0 ; mov ax, dx ; dx express the 'click count' of clock, is our random number and dx, 127 mov bl, dl mov bh, 0 pop dx pop ax ret getRandomNunber endp code ends end start ; finished at 2014.07.26