猜数字游戏, 我想大家都应该玩过, 游戏规则我就不说了.
当初写的时候, 是想尽量少的用中断调用.
mov ah, 2ch
int 21h 该中断调用, 获取时间, 进而来获得伪随机数. 这个其实也可以自己写, 但我实在懒得写了.
mov ah, 0
int 16h 这个用于读取键盘输入
mov ax, 4c00h
int 21h 这个用于退出程序,
再无调用其他的中断.
强烈不建议阅读该程序, 因为写的太烂了. 我承认我确实实现了猜数字游戏该有的功能. 但这个程序写的太烂,
我写该程序并没有进行什么规划就开始写了. 7个多月前, 就把主体写了, 但一直没写生成随机数那个子程序. 于是今晚实在是
忍不了了, 就把它解决了.
不管怎样这目前也算我一个写的汇编代码行数最多的程序. 多少还是有点成就感的.
不管写的多烂, 也算是完成了. 希望自己以后能再接再厉.
有兴趣可以编译,链接了, 执行.
按数字键, 输入数字, 按backspace删除输入数字. 输入4个数字后按回车执行比较, 显示比较结果, 若成功则游戏结束, 可以按回车进行下一局. 在游戏的任何时候都可以按esc建推出游戏.
; guessnum.asm 猜数字游戏
;--------------------------------------------------
; vaddr: 计算屏幕上某一位置对应的显存地址
; 格式: vaddr widthi,page_num ;为了简便这里不使用
; 入口参数: (dh)=行
; (dl)=列
; widthi=屏幕宽(一般为25*80模式)
; 故一般为80
; page_num=所在显存页,一般选0
; 返回值: (di)=显存地址
;--------------------------------------------------
vaddr macro
push ax
push dx
mov al, 80
mul dh
xor dh, dh
add ax, dx
shl ax, 1
mov di, ax
pop dx
pop ax
endm
assume cs:code,ds:data
data segment
msg1 db 'the game of guess number'
msg2 db 'congratulation'
row db 8
col db 30
a db ?
b db ?
s1 db '2468' ; 生成的待猜测数存放位置
d1 db 0,0,0,0 ; 输入的数字存放的位置.
flag db 0,0,0,0,0,0,0,0,0,0
v db ?
data ends
code segment
start: mov ax, data
mov ds, ax
call screen ; 设置屏幕
begin: call random ; 生成随机数存入s1
begin1: mov bx, 0
mov v, 0 ;
call clearflag ; 清除flag标记
mov dh, row
add dh, 3
mov dl, col
add dl, 9
vaddr
call showd1 ; 显示输入
read: mov ah, 0
int 16h
cmp ah, 01 ; 为esc则退出
je exit
cmp ah, 1ch ; 为回车,且已输入四个数则比较
jne other
cmp v, 1 ; 成功后按回车,表示重新游戏
jne nv
call newgame
jmp begin
nv: cmp bx, 4
jne read
cmp v, 2 ; 显示结果后按回车,清除结果
je begin1
call compare
call showans
call testv
jmp read
other: cmp ah, 0eh ; 为backspace,则删除一个字符
jne num ; 不是backspace,则继续比较看其是否为数字的ascii
cmp bx, 0
je read
sub ah, ah
mov al, d1[bx-1]
sub al, 30h
mov si, ax
mov byte ptr flag[si], 0
dec bx
call showd1 ; 显示d1中的字符串
jmp read
num: cmp al, '0'
jb read
cmp al, '9'
ja read
cmp bx, 4
je read
sub ah, ah
mov si, ax
sub si, 30h
mov ah, flag[si]
cmp ah, 1
je read
mov flag[si],1
mov d1[bx], al ; 为数字则存入d1中
inc bx
call showd1 ; 显示d1中的字符串
jmp read
exit: mov ax, 4c00h
int 21h
;-----------------------------------------------------------------
random: push ax
push bx
push cx
push dx
call clearflag
mov ah, 2ch
int 21h
mov ah, 0
mov bl, 10
mov al, dl
div bl
sub bh, bh
mov bl, ah
mov s1, bl
add s1, 30h
mov flag[bx], 1
s12: mov ah, 2ch
int 21h
mov ah, 0
mov bl, 10
mov al, dl
div bl
mov bl, ah
cmp flag[bx], 1
je s12
mov flag[bx], 1
mov s1+1, bl
add s1+1, 30h
s13: mov ah, 2ch
int 21h
mov ah, 0
mov bl, 10
mov al, dl
div bl
mov bl, ah
cmp flag[bx], 1
je s13
mov flag[bx], 1
mov s1+2, bl
add s1+2, 30h
s14: mov ah, 2ch
int 21h
mov ah, 0
mov bl, 10
mov al, dl
div bl
mov bl, ah
cmp flag[bx], 1
je s14
mov flag[bx], 1
mov s1+3, bl
add s1+3, 30h
;
pop dx
pop cx
pop bx
pop ax
ret
;-----------------------------------------------------------------
;------------------------------------------------------------------
; clearflag: 将所有flag值都清零.
;------------------------------------------------------------------
clearflag: push bx
push cx
sub bx, bx
mov cx, 10
cles: mov byte ptr flag[bx],0
inc bx
loop cles
pop cx
pop bx
ret
;-----------------------------------------------------------------
;-----------------------------------------------------------------
screen: push ax
push dx
push di
push si
push cx
push ds
push es
mov ax, 0b800h
mov es, ax
mov di, 0
mov cx, 2000
scrs1: mov byte ptr es:[di], ' '
inc di
mov byte ptr es:[di], 07
inc di
loop scrs1 ; 清屏
mov ax, data
mov ds, ax
mov dh, row
mov dl, col
vaddr
mov si, offset msg1
mov cx, 24
scrs2: mov al, [si]
mov es:[di], al
inc si
inc di
inc di
loop scrs2 ; 显示msg1字符串
add dh, 2
add dl, 8
mov cx, 6
vaddr
scrs3: mov byte ptr es:[di+1], 70h
inc di
inc di
loop scrs3
inc dh
vaddr
mov byte ptr es:[di+1], 70h
add dl, 5
vaddr
mov byte ptr es:[di+1], 70h
mov dh, row
add dh, 4
mov dl, col
add dl, 8
mov cx, 6
vaddr
scrs4: mov byte ptr es:[di+1], 70h
inc di
inc di
loop scrs4
pop es
pop ds
pop cx
pop si
pop di
pop dx
pop ax
ret
;-----------------------------------------------------------------
showd1: push di
push cx
push es
push ax
push dx
push si
mov ax, 0b800h
mov es, ax
mov byte ptr es:[di],' '
mov byte ptr es:[di+2],' '
mov byte ptr es:[di+4],' '
mov byte ptr es:[di+6],' ' ; 先清空已显示的数字
cmp bx, 0 ; 无数字需要显示则退出
je shoexit
mov cx, bx
mov si, 0
shos1: mov al, d1[si]
mov es:[di],al
inc di
mov byte ptr es:[di],07
inc di
inc si
loop shos1
; cmp bx, 4
; je shoexit
shoexit: pop si
pop dx
pop ax
pop es
pop cx
pop di
ret
;-----------------------------------------------------------------
;-----------------------------------------------------------------
showans: push di
push ax
push di
mov ax, 0b800h
mov es, ax
mov byte ptr es:[di],'A'
mov al, a
add al, 30h
mov es:[di+2],al
mov byte ptr es:[di+4],'B'
mov al, b
add al, 30h
mov es:[di+6],al
mov d1, 0
mov d1+1, 0
mov d1+2, 0
mov d1+3, 0
pop es
pop ax
pop di
ret
;-----------------------------------------------------------------
;-----------------------------------------------------------------
compare: push si
push di
push cx
push ax
mov a, 0
mov b, 0
sub si, si
sub di, di
mov cx, 4
cmps1: mov al, s1[si]
cmp al, d1[di]
jne cmpss1
inc a
cmpss1: inc si
inc di
loop cmps1
sub si, si
sub di, di
mov cx, 4
cmps2: mov al, d1[di]
push cx
sub si, si
mov cx, 4
cmpss2: cmp al, s1[si]
jne cmpss3
inc b
cmpss3: inc si
loop cmpss2
pop cx
inc di
loop cmps2
cmp a, 4
jne cmpexit
mov v, 1 ; 成功则设置v为1
jmp cmpexit1
cmpexit: mov v, 2 ; 比较完成但没成功则设置v为2
cmpexit1: pop ax
pop cx
pop di
pop si
ret
;-----------------------------------------------------------------
;-----------------------------------------------------------------
newgame: push dx
push ax
push si
push cx
push es
push di
mov v, 0
mov d1, 0
mov d1+1, 0
mov d1+2, 0
mov d1+3, 0
call showd1
mov dh, row
mov dl, col
add dh, 6
add dl, 4
vaddr
mov ax, 0b800h
mov es, ax
mov si, 0
mov cx, offset row - offset msg2
news : mov al, msg2[si]
mov es:[di],al
inc di
mov byte ptr es:[di],00h
inc di
inc si
loop news
pop di
pop es
pop cx
pop si
pop ax
pop dx
ret
;-----------------------------------------------------------------
;-----------------------------------------------------------------
testv: push dx
push ax
push cx
push di
push si
push es
cmp v, 1
jne tesexit
mov dh, row
mov dl, col
add dh, 6
add dl, 4
vaddr
mov ax, 0b800h
mov es, ax
mov si, 0
mov cx, offset row - offset msg2
tests: mov al, msg2[si]
mov es:[di],al
inc di
mov byte ptr es:[di],08ah
inc di
inc si
loop tests
; jmp tesexit
tesexit: pop es
pop si
pop di
pop cx
pop ax
pop dx
ret
;-----------------------------------------------------------------
code ends
end start