24点游戏实验报告 汇编语言

微机原理实验报告

学院名称

通信与信息工程学院

实验名称

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

八、实验结果: