微机原理实验报告
学院名称
:
通信与信息工程学院
实验名称
:
24点游戏
班级
:
安全0801
学生姓名
:
王宇,吴洁,吴泽鹏,石育妹,魏圆圆
学号(班内序号)
:
060830(31,32,33,34,36)
一、实验题目:
24点游戏
二、实验目的与要求:
1、实验目的:操作者任意输入4个牌张数字(1-9,A算1,花牌不算),程序要给出将这4个数字计算出24的表达式,如果不能计算出这个结果,显示“no answer”;
2、基本要求:(1)图形显示牌张效果;(2)结果显示表达式清晰;(3)若查询结果有超过20%比例不能计算出正确表达式,视为没有达到要求。
三、实验扩展:
1、可以在当前运行状态下,可以重新发牌,进行新一轮的游戏;
2、游戏结束后,可按“Esc”键退出游戏。
四、实验所完成的功能:
1、运行程序,输入四张牌(1—9)后,会自动显示四张牌,并显示牌张效果,其中1显示的是A。
2、命令提示: A-AUTO,SP-RESTART,ESC-QUIT;(SP为空格键)
3、自动部分:按下“A”键后,若有解,则显示运算表达式,若无解,则显示“no answer ! ”;
五、实验代码基本框架:
(1)数据段部分:(Data Segment)
1、定义欢迎界面;
2、定义光标位置;
3、定义方框;
4、自动24点部分数据段;
5、界面显示部分;
6、数据段结束(Data Ends)
(2)代码段部分:(Code Segment)
1、设置BIOS调色板;
2、显示欢迎语句;
3、输入牌号并同时生成花色;
4、输入命令:A-AUTO, SP-RESTART,ESC-QUIT
5、自动24点显示部分;
6、显示部分子程序:显示4个方框;显示牌号;显示花色;
7、设置修改光标位置的子程序;
8、绘制一个方块的子过程;
9、输入牌号子程序;
10、输入数据处理子程序;(转换1-A,及其他数字处理)
11、24点计算函数(5种树的计算函数);
12、5种树的显示函数;
13、结束程序。
六、流程图
一、数据段部分:
数据段部分结束数据段部分开始定义欢迎界面
数据段部分结束
数据段部分开始
定义欢迎界面
定义光标位置
定义方框
自动24点部分数据段
二、代码段部分:
输入牌号及生成随机花色并显示牌张效果显示欢迎语句设置BIOS调色板代码段开始
输入牌号及生成随机花色并显示牌张效果
显示欢迎语句
设置BIOS调色板
代码段开始
输入命令
输入命令
自动24点显示
自动24点显示
各子程序代码段结束
各子程序
代码段结束
1、输入牌号及生成随机花色并显示牌张效果:
开始
开始
CX=0?循环次数CX-1DI+1SI+2将花色送入偏移地址为(DI)的单元内将牌号送入偏移地址为(SI)和(SI+1)的单元内调用输入牌号及生成花色的子程序循环次数送CX存放花色数组偏移地址送DI牌号数组偏移地址送SI
CX=0?
循环次数CX-1
DI+1
SI+2
将花色送入偏移地址为(DI)的单元内
将牌号送入偏移地址为(SI)和(SI+1)的单元内
调用输入牌号及生成花色的子程序
循环次数送CX
存放花色数组偏移地址送DI
牌号数组偏移地址送SI
处理数据 N
处理数据
Y
调用显示四个方框及牌号的子程序
调用显示四个方框及牌号的子程序
2、wait-key输入命令:
开始
开始
判断键盘是否输入A
判断键盘是否输入A
Y
N
判断键盘是否输入空格
判断键盘是否输入空格
Y
N
判断键盘是否输入退出键
判断键盘是否输入退出键
Y
退出程序
退出程序
重新开始程序
重新开始程序
自动24点显示
自动24点显示
3、自动24点显示
调用24点计算函数docal5调用24点计算函数docal4调用24点计算函数docal3调用24点计算函数docal2开始 将输入的数放入dat-g和dat中调用24点计算函数docal1结果=24/?调用24点计算函数docal2结果=24/?
调用24点计算函数docal5
调用24点计算函数docal4
调用24点计算函数docal3
调用24点计算函数docal2
开始
将输入的数放入dat-g和dat中
调用24点计算函数docal1
结果=24/?
调用24点计算函数docal2
结果=24/?
N
Y
结果=24/?
结果=24/?
N
Y
结果=24/?
结果=24/?
N
Y
结果=24/?
结果=24/?
N
Y
结果=24/?
结果=24/?
N调用24点显示函数
调用24点显示函数
显示NO ANSWER
显示NO ANSWER
除数=0?
除数=0?
N
Y
将数100放入trans-val中(说明得数!=24)用idiv除法指令,除以bx退出transval
将数100放入trans-val中(说明得数!=24)
用idiv除法指令,除以bx
退出transval子程序
将余数放入dx中,商放入ax中
dx=0?
N
退出transval子程序商放入
退出transval子程序
商放入trans-val中
七、实验代码:(以上基本框架会在以下代码中有所标注)
;* 运行程序,自己输入4张纸牌,通过命令键可实现自动运算24点,并将结果显示在纸牌下方 *
;* 命令提示: A-AUTO,SP-RESTART,ESC-QUIT
;* 自动部分:若有解,则显示运算表达式,若无解,则显示' NO ANSWEWR ! '
;///////////////////////////显示部分数据段//////////////////////////////////////////
;***************************定义欢迎界面*****************************
DATA segment
NOTE1 DB 0AH,0DH,' WELCOME TO THE 24 POINTS GAME ','$'
NOTE2 DB 0AH,0DH,' A-AUTO,SP-RESTART,ESC-QUIT','$'
NOTE3 DB 0AH,0DH,' no answer! ','$'
NOTE4 DB 0AH,0DH,' Input the numbers:','$'
;***************************定义光标位置********************
X_POS DB 10 ;行
Y_POS DB 10 ;列
;******************定义方框*************************************
ypos dw ? ;定义列起始位置
xpos dw ? ;定义行起始位置
color db ? ;0-无色,1-绿,2-红,3-橘黄,4-橙红,5-紫红,7-白,8*-灰,9-蓝,10-绿,11-青绿,12-粉红,14-黄,15-白
cnt1 DW 0 ;定义方框宽度
cnt2 DW 0 ;定义方框长度
len db 0
dat_disp db 4 dup(' ') ;显示的牌的数字
dat_g dw 4 dup(?) ;输入的数的数组
Input_d dw ?
card_ran db ?
card db 4 dup (?) ;牌的花色
;//////////////////////////////自动24点部分数据段/////////////////
dat dw 4 dup(?)
B DW ?
i db 0 ;i,j,k循环变量
j db 0
k db 0
t1 dw ? ;临时计算结果
t2 dw ?
t3 dw ?
trans_val dw ? ;运算结果
docal_1 dw ? ;树的计算结果
docal_2 dw ?
docal_3 dw ?
docal_4 dw ?
docal_5 dw ?
buff1 db 11 dup(?),0dh,0ah,'$' ;各树输出结果缓存
buff2 db 11 dup(?),0dh,0ah,'$'
buff3 db 11 dup(?),0dh,0ah,'$'
buff4 db 11 dup(?),0dh,0ah,'$'
buff5 db 11 dup(?),0dh,0ah,'$'
opstr db '+','-','*','/'
nosolve_flag db 0 ;nosolve标志
data ends
;/////////////////////界面显示部分/////////////////////////////
code segment
ASSUME CS:code,DS:data
start:
MOV AX,data
MOV DS,AX
;************************设置BIOS调色板****************************
mov ah, 00h ;设置绘图模式
mov al, 12h ;16色图形模式
int 10h
mov ah, 0bh ;设置调色板
mov bh, 0Fh ;调色板ID
mov bl, 02h ;颜色
int 10h
;**************************显示欢迎语句*****************************
LEA DX,NOTE1
MOV AH,09H
INT 21H
LEA DX,NOTE2
MOV AH,09H
INT 21H
MOV B,0260H
MOV AH,2
MOV BX,0
MOV DX,B
INT 10H
MOV SI,OFFSET NOTE4
MOV DX,SI
MOV AH,9
INT 21H
;************************ *输入牌号及随机花色************************
lea si,dat_g
LEA DI,CARD
mov cx,4
MOV B,0370H
Input_loop:
call Input_g
mov bx,Input_d
mov word ptr[si],bx
MOV AL,CARD_RAN
MOV BYTE PTR[DI],AL
inc si
inc si
INC DI
INC B
loop Input_loop
call deal_data
call FRAME1
call FRAME2
;******************输入命令:A-AUTO ,SP-RESTART,ESC-QUIT *************
wait_key:
MOV AH,08H
INT 21H
cmp al,'A'
JZ AUTO
CMP AL,1BH
JZ EXIT
CMP AL,20H
JZ START
JMP WAIT_KEY
;/////////////////////////////自动24点显示///////////////////////////
AUTO:
part_24:
MOV X_POS,12 ;行,定义光标位置,显示24点算式
MOV Y_POS,24 ;列
CALL POSITION
mov cx,4
lea si,dat_g ;将数放入dat_g和dat中
lea di,dat
copy_data: mov ax,word ptr [si]
mov word ptr[di],ax
inc si
inc si
inc di
inc di
loop copy_data
loop1: ;显示自动运算结果
loop2:
loop3:
call docal1 ;调用各树并产生结果与24比较,相等则显示该运算表达式
cmp docal_1,24
jz disp1
call docal2
cmp docal_2,24
jz disp2
call docal3
cmp docal_3,24
jz disp3
call docal4
cmp docal_2,24
jz disp4
call docal5
cmp docal_5,24
jz disp5
jmp no_solve
disp1: call display1 ;显示运算表达式并返回到wait_key处
jmp wait_key
disp2: call display2
jmp wait_key
disp3: call display3
jmp wait_key
disp4: call display4
jmp wait_key
disp5: call display5
jmp wait_key
loop1_2: jmp loop1
no_solve:inc k ;遍历各运算符以确定是否有解,无解则显示NO ANSWER
cmp k,4
jnz loop3
inc j
mov k,0
cmp j,4
jnz loop2
inc i
mov j,0
mov k,0
cmp i,4
jnz loop1_2
LEA DX,NOTE3
MOV AH,09H
INT 21H
mov nosolve_flag,1
jmp wait_key
key_in:
mov ah,08h
int 21h
cmp al,1bh ;esc 退出
jz exit
cmp al,20h
jz start
exit:
mov ah,4ch
int 21h
;///////////////////////////显示部分////////////////////////////
;****************************显示4个方框 *************************
FRAME1 PROC
PUSHF
MOV xpos,70 ;定义行
MOV ypos,60 ;定义列
mov color,13 ;存像素值
CALL RECT
MOV xpos,70
MOV ypos,160
mov color,9
CALL RECT
MOV xpos,70
MOV ypos,260
mov color,14
CALL RECT
MOV xpos,70
MOV ypos,360
mov color,12
CALL RECT
MOV xpos,70
MOV ypos,460
mov color,0
CALL RECT
popf
RET
FRAME1 ENDP
;**************************显示牌号******************************
FRAME2 PROC
PUSHF
lea si,dat_disp
MOV X_POS,7 ;行
MOV Y_POS,12 ;列
CALL POSITION
MOV AL,[si]
MOV BL,0bH ;像素值
MOV AH,0EH
INT 10H
MOV X_POS,7
MOV Y_POS,25
CALL POSITION
MOV AL,[si+1]
MOV BL,0bH
MOV AH,0EH
INT 10H
MOV X_POS,7
MOV Y_POS,37
CALL POSITION
MOV AL,[si+2]
MOV BL,0bH
MOV AH,0EH
INT 10H
MOV X_POS,7
MOV Y_POS,49
CALL POSITION
MOV AL,[si+3]
MOV BL,0bH
MOV AH,0EH
INT 10h
;***************************显示花色***************************
MOV X_POS,5 ;行
MOV Y_POS,8 ;列
CALL POSITION
MOV AL,[DI]
MOV BL,0AH ;像素值
MOV AH,0EH
INT 10H
MOV X_POS,5
MOV Y_POS,21
CALL POSITION
MOV AL,[DI+1]
MOV BL,0AH
MOV AH,0EH
INT 10H
MOV X_POS,5
MOV Y_POS,33
CALL POSITION
MOV AL,[DI+2]
MOV BL,0AH
MOV AH,0EH
INT 10H
MOV X_POS,5
MOV Y_POS,46
CALL POSITION
MOV AL,[DI+3]
MOV BL,0AH
MOV AH,0EH
INT 10H
POPF
RET
FRAME2 ENDP
;***********************设置/修改光标的位置**************************
POSITION PROC NEAR
PUSH BX
PUSH DX
MOV BH,00H ;页码
MOV DH,X_POS ;行
MOV DL,Y_POS ;列
MOV AH,02H ;设置光标位置
INT 10H
POP DX
POP BX
POSITION ENDP
;***********************绘制一个方块的子过程***********************
RECT proc near
push ax
push dx
push cx
mov ah, 0ch
mov al, color ;存像素值
mov dx, xpos ;存入行0-199
mov cnt1,120 ;方框宽度
disp1_r:
mov cx, ypos ;存入列0-639
mov cnt2,80 ;方框长度
disp2_r:
int 10h
inc cx
dec cnt2
jnz disp2_r
inc dx
dec cnt1
jnz disp1_r
pop ax
pop dx
pop cx
Ret
Rect endp
;***********************牌号的输入及随机花色************************
Input_g proc
PUSH CX
PUSH DX
PUSH BX
MOV AH,2
MOV BX,0
MOV DX,B
INT 10H
;输入部分
MOV AH,01H
INT 21H
SUB AL,30H
MOV AH,0
MOV Input_d,AX
;随机花色
MOV AX,0
MOV AL,DL
CBW
MOV BL,4
DIV BL
ADD AH,3
MOV CARD_RAN,AH
POP BX
POP DX
POP CX
ret
Input_g endp
;************************输入数据处理的子程序************************
deal_data proc
push bx
push cx
lea si,dat_g
lea di,dat_disp
mov cx,4
deal_on: mov word ptr bx,[si] ;转换1_A
cmp bx ,1
jz deal1
jmp deal_others
deal1: mov word ptr [si],1
mov byte ptr [di],'A'
jmp deal_over
deal_others:add bx,30h
mov byte ptr[di],bl
deal_over: inc si
inc si
inc di
loop deal_on
pop cx
pop bx
ret
deal_data endp
;//////////////////////// 24点计算函数/////////////////////////////
;/***************************5种树的计算函数******************
;/********************/(1*2)*(3*4)****************1
docal1 proc
lea si,dat
mov ax,[si]
mov bx,[si+2] ;计算(1*2)
mov dl,i
call transval
mov dx,trans_val ;将计算结果保存
mov t1,dx
mov ax,[si+4]
mov bx,[si+6] ;计算(3*4)
mov dl,k
call transval
mov dx,trans_val
mov t2,dx
mov ax,t1
mov bx,t2
mov dl,j
call transval ;;计算(1*2)*(3*4)
mov dx,trans_val
mov docal_1,dx
ret
docal1 endp
;/*********************/1*(2*(3*4))*********************2
docal2 proc
lea si,dat
mov ax,[si+4]
mov bx,[si+6]
mov dl,k
call transval
mov dx,trans_val
mov t1,dx
mov ax,[si+2]
mov bx,t1
mov dl,j
call transval
mov dx,trans_val
mov t2,dx
mov ax,[si]
mov bx,t2
mov dl,i
call transval
mov dx,trans_val
mov docal_2,dx
ret
docal2 endp
;/*******************/1*((2*3)*4)*********************3
docal3 proc
lea si,dat
mov ax,[si+2]
mov bx,[si+4]
mov dl,j
call transval
mov dx,trans_val
mov t1,dx
mov ax,t1
mov bx,[si+6]
mov dl,k
call transval
mov dx,trans_val
mov t2,dx
mov ax,[si]
mov bx,t2
mov dl,i
call transval
mov dx,trans_val
mov docal_3,dx
ret
docal3 endp
;/*****************/((1*2)*3)*4************************4
docal4 proc
lea si,dat
mov ax,[si]
mov bx,[si+2]
mov dl,i
call transval
mov dx,trans_val
mov t1,dx
mov ax,t1
mov bx,[si+4]
mov dl,j
call transval
mov dx,trans_val
mov t2,dx
mov ax,t2
mov bx,[si+6]
mov dl,k
call transval
mov dx,trans_val
mov docal_4,dx
ret
docal4 endp
;/******************/(1*(2*3))*4*5************************
docal5 proc
lea si,dat
mov ax,[si+2]
mov bx,[si+4]
mov dl,j
call transval
mov dx,trans_val
mov t1,dx
mov ax,[si]
mov bx,t1
mov dl,i
call transval
mov dx,trans_val
mov t2,dx
mov ax,t2
mov bx,[si+6]
mov dl,k
call transval
mov dx,trans_val
mov docal_5,dx
ret
docal5 endp
;//////////////////////////////////
;四则运算函数 //
;入口参数:al,bl,dl //
;结果保存在trans_val 中 //
;dl的值: 0:'+' 1:'-' 2:'*' 3:'/' //
;//////////////////////////////////
transval proc
push ax ;保护现场
push bx
push cx
push dx
cmp dl,0 ;将传送过来的数进行+或-或*或/运算
jz ad_d
cmp dl,1
jz su_b
cmp dl,2
jz mu_l
cmp dl,3
jz di_v
jmp exit_t
ad_d: add ax,bx
mov trans_val,ax
jmp exit_t
su_b: sub ax,bx
mov trans_val,ax
jmp exit_t
mu_l: imul bx
mov trans_val,ax
jmp exit_t
di_v: cmp bx,0 ;分母是0
jz div_2
cwd
idiv bx ;判断能不能除尽
cmp dx,0
jnz div_2
mov trans_val,ax
jmp exit_t
div_2:mov trans_val,100 ;排除有余数的情况
exit_t:
pop dx ;恢复现场
pop cx
pop bx
pop ax
ret
transval endp
;-----------------------------五种树的显示函数-----------------------
;显示方式为:dat[0],op[ii],dat[1],op[jj],dat[2],op[kk],dat[3]
;/*********************树1*******//(1*2)*(3*4)
display1 proc
push bx
push dx
lea bx,dat_disp
lea si,opstr
lea di,buff1
mov byte ptr [di],'('
mov dl,byte ptr[bx]
mov byte ptr [di+1],dl
push bx
xor bh,bh
mov bl,i
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+2],dl
mov dl,byte ptr[bx+1]
mov byte ptr [di+3],dl
mov byte ptr [di+4],')'
push bx
xor bh,bh
mov bl,j
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+5],dl
mov byte ptr [di+6],'('
mov dl,byte ptr[bx+2]
mov byte ptr [di+7],dl
push bx
xor bh,bh
mov bl,k
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+8],dl
mov dl,byte ptr[bx+3]
mov byte ptr [di+9],dl
mov byte ptr [di+10],')'
lea dx,buff1
mov ah,09h
int 21h
pop dx
pop bx
ret
display1 endp
;/*********************树2******//1*(2*(3*4))
display2 proc
push bx
push dx
lea bx,dat_disp
lea si,opstr
lea di,buff2
mov dl,byte ptr[bx]
mov byte ptr [di],dl
push bx
xor bh,bh
mov bl,i
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+1],dl
mov byte ptr[di+2],'('
mov dl,byte ptr[bx+1]
mov byte ptr[di+3],dl
push bx
xor bh,bh
mov bl,j
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+4],dl
mov byte ptr [di+5],'('
mov dl,byte ptr[bx+2]
mov byte ptr [di+6],dl
push bx
xor bh,bh
mov bl,k
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+7],dl
mov dl,byte ptr[bx+3]
mov byte ptr [di+8],dl
mov byte ptr [di+9],')'
mov byte ptr [di+10],')'
lea dx,buff2
mov ah,09h
int 21h
pop dx
pop bx
ret
display2 endp
;/*********************树3******* //1*((2*3)*4)
display3 proc
push bx
push dx
lea bx,dat_disp
lea si,opstr
lea di,buff3
mov dl,byte ptr[bx]
mov byte ptr [di],dl
push bx
xor bh,bh
mov bl,i
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+1],dl
mov byte ptr [di+2],'('
mov byte ptr [di+3],'('
mov dl,byte ptr[bx+1]
mov byte ptr [di+4],dl
push bx
xor bh,bh
mov bl,j
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+5],dl
mov dl,byte ptr[bx+2]
mov byte ptr [di+6],dl
mov byte ptr [di+7],')'
push bx
xor bh,bh
mov bl,k
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+8],dl
mov dl,byte ptr[bx+3]
mov byte ptr [di+9],dl
mov byte ptr [di+10],')'
lea dx,buff3
mov ah,09h
int 21h
pop dx
pop bx
ret
display3 endp
;/*********************树4**************//((1*2)*3)*4
display4 proc
push bx
push dx
lea bx,dat_disp
lea si,opstr
lea di,buff4
mov byte ptr [di],'('
mov byte ptr [di+1],'('
mov dl,byte ptr[bx]
mov byte ptr [di+2],dl
push bx
xor bh,bh
mov bl,i
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+3],dl
mov dl,byte ptr[bx+1]
mov byte ptr [di+4],dl
mov byte ptr [di+5],')'
push bx
xor bh,bh
mov bl,j
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+6],dl
mov dl,byte ptr[bx+2]
mov byte ptr [di+7],dl
mov byte ptr [di+8],')'
push bx
xor bh,bh
mov bl,k
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+9],dl
mov dl,byte ptr[bx+3]
mov byte ptr [di+10],dl
lea dx,buff4
mov ah,09h
int 21h
pop dx
pop bx
ret
display4 endp
;/*********************树5*******//(1*(2*3))*4
display5 proc
push bx
push dx
lea bx,dat_disp
lea si,opstr
lea di,buff5
mov byte ptr [di],'('
mov dl,byte ptr[bx]
mov byte ptr [di+1],dl
push bx
xor bh,bh
mov bl,i
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+2],dl
mov byte ptr [di+3],'('
mov dl,byte ptr[bx+1]
mov byte ptr [di+4],dl
push bx
xor bh,bh
mov bl,j
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+5],dl
mov dl,byte ptr[bx+2]
mov byte ptr [di+6],dl
mov byte ptr [di+7],')'
mov byte ptr [di+8],')'
push bx
xor bh,bh
mov bl,k
mov dl,byte ptr[si+bx]
pop bx
mov byte ptr [di+9],dl
mov dl,byte ptr[bx+3]
mov byte ptr [di+10],dl
lea dx,buff5
mov ah,09h
int 21h
pop dx
pop bx
ret
display5 endp
;//////////////////////////////程序结束/////////////////////////
code ends
end start
八、实验结果: