21,459
社区成员
发帖
与我相关
我的任务
分享
DATA SEGMENT
LastRand db 01011101b ;seed
DisplayStr db 10,13
FirstNumStr db 2 dup (20h)
OpStr db '+'
SecondNumStr db 3 dup (20h),'='
Ans db 4 dup (20h),'$'
FirstNum db 0
SecondNum db 0
Op db 0 ;0 = [+] , 1= [-]
OpCount db 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV ES,AX
Restart:
;初始化
mov byte ptr OpStr,'+' ;正数符
mov ax,2020h
mov word ptr Ans,ax
mov word ptr Ans+2,ax
next0: ;以下乱取得二数和加减运算子
;取第1数
mov al,LastRand
call Random ;get al = 0-255
mov LastRand,al
cmp al,99
ja next0
cmp al,0
jz next0
cmp FirstNum,al
jz next0 ;不能和上次第1数相同
mov FirstNum,al ;取得第一数1-99
;----- ;取第运算子+ / -
mov al,LastRand
call Random
and al,00000001b
mov ah,al
xor ah,op ;上次运算子和今次运算子比较
jnz next0a ;不同
inc OpCount ;若二值相同到此,累加
cmp OpCount,2 ;运算子不能超过3次相同
jbe next0b ;未到3次
xor al,1 ;运算子取反
next0a:
mov OpCount,0 ;重设运算子计数
next0b:
mov op,al
test al,1 ;bit0设定0为正,1为负
jz next
mov Op,1
mov OpStr,'-' ;运算子[-]设定
next: ; --------取第2数
mov al,LastRand
call Random
mov LastRand,al
cmp al,99
ja next
cmp al,0
jz next
cmp FirstNum,al ;不能和第1值相同
jz Next
mov SecondNum,al ;取得第2数1-99
;-----
next2: ;以下二数转ascii,存入显示字符串
mov al,FirstNum
aam
or ax,3030h
xchg al,ah
mov word ptr FirstNumStr,AX
mov al,SecondNum
aam
or ax,3030h
xchg al,ah
mov word ptr SecondNumStr,AX
;---- 以下计算二数加或减
mov ah,SecondNum
mov al,FirstNum
test Op,1 ;0=+ , 1= -
jz next2a
sub al,ah ;二数相减
jmp short next2b
next2a:
add al,ah ;二数相加
next2b:
jnc next3 ;cf=1结果是负
neg al ;转正
mov byte ptr Ans,'-' ;负数符
next3:
mov di,offset Ans + 1
xor cx,cx ;以下结果转ascii
aam ;bcd加法调整
push ax ;保存个位
inc cx ;累加
cmp ah,10 ;是否有百位
jb next4 ;没有
mov al,ah ;送十位百位入al
aam ;bcd加法调整
push ax ;保存十位
inc cx ;累加
next4:
mov al,ah ;取第1位,可能是十位或百位
cmp al,0 ;第1位是否0
jnz next4a ;不是
mov al,20h-30h ;是0, 则以空白取代,随后代码加30h,将变回空白20h
dec di ;因第1位是0,补空白后随后数字移前
next4a:
push ax ;保存第1位
inc cx ;累加
next5:
pop ax ;栈取回
add al,30h ;转ascii
stosb ;存至结果字符串
loop next5 ;下一个
mov ah,9 ;印出整条数式
mov dx,offset DisplayStr
int 21h
mov ax,0c07h ;暂停
int 21h
cmp al,1bh ;esc ?
jz quit
jmp Restart ;重来一条
quit:
mov ah,4ch ;离开
int 21h
;-------------------------
;随机值子程序(利用int1Ah, ah=0获取bios系统累加时数),
;传入:al乱数种子,可以是上次随机值
;传回:al = 0-255
回0-255
Random:
push dx
push cx
push bx
mov bh,al ; 取上次随机值
mov ah,0
int 1Ah ;传回cx:dx为bios系统累加时数(由凌晨起,每1/18秒累加一次)
mov al,dl ;以下弄乱结果,让随机性大些
xor al,dh
xor al,bh
xor cx,dx
R10:
add al,dl
loop R10
pop bx
pop cx
pop dx
ret
;---------------------------------------
CODE ENDS
END START