邹伟汇编实验报告.docx

上传人:b****0 文档编号:9858169 上传时间:2023-05-21 格式:DOCX 页数:60 大小:47.69KB
下载 相关 举报
邹伟汇编实验报告.docx_第1页
第1页 / 共60页
邹伟汇编实验报告.docx_第2页
第2页 / 共60页
邹伟汇编实验报告.docx_第3页
第3页 / 共60页
邹伟汇编实验报告.docx_第4页
第4页 / 共60页
邹伟汇编实验报告.docx_第5页
第5页 / 共60页
邹伟汇编实验报告.docx_第6页
第6页 / 共60页
邹伟汇编实验报告.docx_第7页
第7页 / 共60页
邹伟汇编实验报告.docx_第8页
第8页 / 共60页
邹伟汇编实验报告.docx_第9页
第9页 / 共60页
邹伟汇编实验报告.docx_第10页
第10页 / 共60页
邹伟汇编实验报告.docx_第11页
第11页 / 共60页
邹伟汇编实验报告.docx_第12页
第12页 / 共60页
邹伟汇编实验报告.docx_第13页
第13页 / 共60页
邹伟汇编实验报告.docx_第14页
第14页 / 共60页
邹伟汇编实验报告.docx_第15页
第15页 / 共60页
邹伟汇编实验报告.docx_第16页
第16页 / 共60页
邹伟汇编实验报告.docx_第17页
第17页 / 共60页
邹伟汇编实验报告.docx_第18页
第18页 / 共60页
邹伟汇编实验报告.docx_第19页
第19页 / 共60页
邹伟汇编实验报告.docx_第20页
第20页 / 共60页
亲,该文档总共60页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

邹伟汇编实验报告.docx

《邹伟汇编实验报告.docx》由会员分享,可在线阅读,更多相关《邹伟汇编实验报告.docx(60页珍藏版)》请在冰点文库上搜索。

邹伟汇编实验报告.docx

邹伟汇编实验报告

汇编报告

个人信息:

邹伟200630473261 2006级计算机科学与技术2班计算机科学与工程学院

报告说明:

上次实验课做的是2.2,在一个字符串中搜寻子字符串,两层循环就可以解决了,此次报告根据自己的兴趣编了个简单的游戏,模仿经典游戏俄罗斯方块。

左右方向键控制方块的水平位置,上方向键旋转方块,END键水平翻转之。

有简单的积分功能,并能根据得分多少调整游戏难度,即方块下落速度。

游戏甚少创新,权为练笔。

程序说明:

游戏有一个依得分而改变的周期,在每一个周期中,用10h号BIOS中断调用检查键盘缓冲是否为空,若不为空,则读出缓冲数据,根据输入指示,调整游戏内部状态,最后根据内部记录的状态用适当的方法表现在屏幕上。

1.主程序流程:

1.初始化游戏环境:

a)清除得分,清空屏幕,初始化相关数据结构

b)产生两个方块组,一个为即将显示的,一个为下一个要显示的。

2.进入游戏循环:

a)延时,达到一定的游戏周期,在此期间也检查用户输入

b)根据输入,应用相应功能,如:

ESC键则跳至4,控制方向键则检查并改变当前方块位置响应输入,F3键主动提高游戏关数,DEL键游戏暂停……。

c)根据b)中更新的内部数据状态,执行相应检查,如:

是否满行?

是否游戏结束?

是否游戏完成?

……

3.无条件跳转至2.

4.退出程序

2.附加说明:

a)随机数的的产生,首先从CMOS实时钟读取的秒数作为随机数的初始值,其后再根据线性同余法产生下一个数。

b)游戏区域暂定为12*20,为了纪录区域中每个格子是否已被方块占据,用了一个长度为20的字数组,每个字的一位代表区域中的一个方格,这样计算满行时容易判断,设/置位也较为容易。

不过由于16位汇编指令中并没有bt之类位操作指令所以,测试某位是否置位时,也相当令人不快。

c)为了更好的控制方块左右移动以及完成旋转水平、翻转等操作,在方块组中选取了一个方块作为参照点,极大简化了编写代码的过程。

d)游戏难度,具体到此游戏就是方块自动下落的速度,通过设置延时长短控制,随着得分的增加,Level也增加,所对应的延时缩短,下落速度加快,为了减小游戏复杂度,在较高关数时方块组形状(共16种,其中2种相同,为仅一个格的穿透方块,设为2增加出现概率)趋于正常。

e)输入的获取,首先调用INT10h的1号功能,判断键盘缓冲区是否为空,若不为空再用0号功能读取,以读取到的输入改变内部状态,即方块位置、游戏状态等。

编写步骤:

1.先构思出一个大概的框架

2.将构建出的框架上.逐步分解

3.逐步添加子程序

4.不断添加代码、DEBUG,最后测试。

 

结果(部分画面截图):

游戏操作说明:

←方块组左移↑旋转

→右移↓急速下落

End水平翻转Delete暂停

F2主动提升程序关数

F3与F2相反

F1下落方块组颜色一致或不一致

左图为程序开始运行时,

得分为0,当前关为0

 

得分规则:

2*一次性消去的行数-1

左图为游戏暂停中,得分为126

已接近通过要求。

继续运行后,

将使游戏达到完成状态。

左图为游戏结束时显示的一个随机画面^_^,

按任意键重新开始

 

游戏完成(通关),显示的画面与此差不多,随

后退出程序。

 

分析与讨论:

1.虽然是用汇编语言编写代码,现代一些优秀的编程思想仍然是极为有用的,如面向对象,能很大程度为编写代码提供导航。

思维决不局限于所用的编程语言,绝大部分编程语言在功能上是完全可以等价的,而思维决定一切,C到C++的发展,功能上并无不同,不过在语法上C++为我们提供了便利,对事物的理解也更为直观。

如果用VC++写此程序就不用那么艰难了。

不过,编写代码过程中很多体悟却不能仅通过几行高级语言的代码所能得到的。

2.程序虽说不算大,但为了更好的控制其变化,我使用了tortoiseSVN工具,其对版本的控制程度非同一般,源代码交给它,非常放心。

同时IDE用的是MasmPlus,至少它提供了语法高亮显示、子程序快速跳转(其实也不够快)、快速检索等功能。

3.Makefile文件的使用也省了不少事,通常是交待它一下怎样通过编译、连接出最终可执行文件后就不用管它了。

所以说好的工具仍是不可忽视的。

结论:

所谓万事开头难,像汇编这样非常不让人省心的语言,看来看去就那几个单调的指令,阅读别人的代码,总有些乏味,只有真正开始自己编写时,才能知道其实它并不难,相反它把所有细节全部展现在我们面前,不像有些高级语言为了通用性,隐藏了很多细节。

在用高级语言编写代码的时候,总觉得有些糊涂度日。

不过话说回来,两者之间的生产效率却不是汇编所能企及的。

在用汇编写代码时,每一条指令的执行都能直接感受其变化到,这时候需要有十分的耐心。

有时候一个不留神寄存器写错了名,半天没得到自己想要的结果还不知道错在哪。

我在编写此程序过程中,就曾有写错的时候,浪费了不少时间。

所以随时DEBUG是必须的,一旦错误扩大了范围,要找到它是要费很多手脚的。

最后,在编任何或大或小的程序之前都需要事先有个清晰的规划,然而我却通常是想到哪写到哪,最后做了不少无用功,可惜了那宝贵的时间。

源代码:

共4个文件,说明如下:

1.makefile :

编译出可执行文件的一些规则,需make工具来解析。

2.game.h :

程序中所需的各种常量及一些数据结构的定义,集中管理,便于

修改

3.entry.asm:

程序的入口点,包含开始一个游戏的无穷循环。

4.game.asm:

程序主体,一个代码段一个数据段一个堆栈段。

●文件名称:

makefile

文件说明:

在命令行上直接运行make即可生成最终可执行文件cnb.exe

-------makefile----start----------

#此文件用于描述源程序之间的相互关系并自动完成维护编译工作,简单而有效

#解析此文件需要make工具,MinGW(C++IDE)中带有

ASM=ml

ASM=ml

LINK=ml

MODEL_FLAG=/c/nologo

MODELS=entry.objgame.obj

all:

cnb.exe

 

%.obj:

%.ASMgame.h

$(ASM)$(MODEL_FLAG)$<

cnb.exe:

$(MODELS)

$(LINK)/Fecnb.exe$(MODELS)

cnb

clean:

rm*.obj

cls

dir

-----------makefile--------end--------

 

●文件名称:

game.h

---------game.h---start--------

;摘要:

程序中所需的各种常量及一些数据结构的定义,集中管理,便于修改

;游戏状态

GS_RUNNINGequ0

GS_PAUSEDequ1

GS_OVERequ2

;最高可达到的关数

LEVEL_LIMITTequ15

;游戏区域起始位置及大小

GM_LEFTequ25

GM_TOPequ4

GM_WIDTHequ12

GM_HEIGHTequ20

GM_MASKequ(1SHLGM_WIDTH-1)

;功能键扫描码

KEY_ESCequ1h;ESC

KEY_LEFTequ4bh;LEFT

KEY_RIGHTequ4dh;RIGHT

KEY_DOWNequ50h;DOWN

KEY_TURNequ4fh;End

KEY_PAUSEequ53h;Delete

KEY_ROLATEequ48h;UP

KEY_QUICKLYequ3dh;F3

KEY_SLOW_DOWNequ3ch;F2

KEY_COLOR_SAMEequ3bh;F1

CHAR_CLEARequ'';擦除字符,空格

CHAR_BRICKequ2;方块外形,头形

;0黑1深蓝2绿3蓝4红5紫6黄7灰白,最高位置1则高亮显示

COLOR_CLEAR equ0h

COLOR_DIED_BRICKequ08h

COLOR_TITTLEequ7;

COLOR_NUMBERequ3or8

;屏幕上各说明文字或装饰物的坐标,皆为相对游戏场地左上角

X_NEXT_BRICKequ-5

Y_NEXT_BRICKequ3

Y_LBOUND_CHARequ17

Y_RBOUND_CHARequ16

Y_BOUND_COLORequ2or8;blue

X_UBOUND_CHARequ15

X_DBOUND_CHARequ15

X_BOUND_COLORequ2or8;green

X_STARTequ(GM_WIDTH-1)/2

Y_STARTequ-1

X_SCORE_STRequ-10

X_LEVEL_STRequX_SCORE_STR

X_adjustLevelDelt_STRequX_SCORE_STR-4

Y_SCORE_STRequ5

Y_LEVEL_STRequY_SCORE_STR+2

Y_adjustLevelDelt_STRequY_LEVEL_STR+2

X_SCORE_POSequ-3

X_LEVEL_POSequX_SCORE_POS

X_adjustLevelDelt_POSequX_SCORE_POS

Y_SCORE_POSequY_SCORE_STR+1

Y_LEVEL_POSequY_LEVEL_STR+1

Y_adjustLevelDelt_POS

 equY_adjustLevelDelt_STR+1

X_GAME_OVERequ-10

X_JUDGE_STRequX_GAME_OVER+5

X_GAME_NAMEequGM_WIDTH/2-4

Y_GAME_NAMEequ-1

Y_GAME_OVERequ-3

Y_JUDGE_STRequY_GAME_OVER+1

;相应键所对应的相应功能入口地址的偏移

DIR_RIGHTequ0

DIR_LEFTequ2*1

DIR_DOWNequ2*2

DIR_ROTATEequ2*3

DIR_DOWN_COMPLETEequ2*4

DIR_TURNequ2*5

KEY_WRONG_DIRequ2*11

;坐标结构

Posstruc

pos_bXdb?

pos_bYdb?

Posends

;单个方块

Brickstruc

;相对基块的坐标

b_sPosPos<>

Brickends

 

;方块组ManyBrickstruc

;方块个数

mb_bCntdw?

;容量固定为4

mb_sBrickBrick4dup(<>)

;多个方块中所选取的基块的坐标,也是相对游戏场左上角而言

mb_sPosPos<>

;此元素的颜色

mb_bColordb?

ManyBrickends

;游戏类,

GameAppstruc

;玩家得分

ga_scoredw?

;游戏状态

ga_statedw?

;游戏地图,相应位置位则有方块在此

ga_mapdwGM_HEIGHTdup(0FFFFh)

GameAppends

--------game.h--------end-----------

●文件名称:

entry.asm

--------entry.asm-----start---------

;Copyleft(c)2007,Godreservedallrights.

;

;当前版本:

0.2

;作者:

邹伟

;完成日期:

2007年12月21日

;摘要:

整个程序从start开始执行,并从main_quit退出

publicmain_quit,restart_the_game

externGA_gameInit:

far,GA_gameCircle:

far,setDSAndES:

far,stackPoint:

byte

assumecs:

EntryCode

EntryCodesegment

start:

callsetDSAndES

restart_the_game:

movsp,offsetstackPoint

main_do_forerer:

callGA_gameInit

;进入游戏循环,直到结束、完成或主动退出

callGA_gameCircle

jmpmain_do_forerer

;按ESC键或整个游戏完成时,跳到这里

main_quit:

;清除屏幕

movah,00h

moval,03h

int10h

;返回DOS

movax,4c00h

int21h

EntryCodeends

endstart

---------entry.asm-----end-----------

●文件名称:

game.asm

---------game.h-------start----------

;Copyleft(c)2007,Godreservedallrights.

;

;当前版本:

0.11

;作者:

邹伟

;完成日期:

2007年12月23日

;摘要:

各主要子程序都在此间

;说明:

程序中用于输出字符的位置未加说明则默认为相对于游戏区域左上角即(GM_LEFT,GM_TOP)

publicsetDSAndES,GA_gameInit,

GA_gameCircle,stackPoint

externmain_quit:

far,restart_the_game:

far

includegame.h

;设置块坐标的宏

assignPosmacrox,y

mov(Brickptr[si]).b_sPos.pos_bX,x

mov(Brickptr[si]).b_sPos.pos_bY,y

addsi,sizeBrick

endm

assignBasemacrox,y

mov(ManyBrickptr[di]).mb_sPos.pos_bX,x

mov(ManyBrickptr[di]).mb_sPos.pos_bY,y

endm

assumecs:

GameCode,

ds:

MainData,

ss:

StackSpase

GameCodesegment

 

;游戏循环---不断获取输入,根据与定义规则合理的转化为输出

GA_gameCircleprocfar

GA_gameCircle_again:

movdir,KEY_WRONG_DIR

leabx,levelFPS

movdi,level

adddi,challenge

cmpdi,LEVEL_LIMITT

jbelevel_ok

movdi,LEVEL_LIMITT

level_ok:

shldi,1

movcx,[bx+di]

wast_time:

calldelay

cmpdir,KEY_WRONG_DIR

jemay_be_life_is_long

callBrick_goNext

movdir,KEY_WRONG_DIR

callManyBrick_drawSelf

may_be_life_is_long:

loopwast_time

cmpdir,KEY_WRONG_DIR

jzuser_press_no_dir_key

callBrick_goNext

user_press_no_dir_key:

movdir,DIR_DOWN

callBrick_goNext

cmpgame.ga_state,GS_OVER

jzGA_over

callManyBrick_drawSelf

jmpGA_gameCircle_again

GA_over:

calldoGameOver

ret

GA_gameCircleendp

;每次游戏开始时的初始化调用

GA_gameInitprocfar

callclrScreen

;hidethecursor

movch,020h

movcl,020h

movah,01h

int10h

;初始化随机序列的第一个数,读取BIOS提供的当前秒

xoral,al

out70h,al

inax,71h

movseed,ax

;初始化,如:

得分,游戏状态,游戏地图

movchallenge,0

movgame.ga_score,0

movgame.ga_state,GS_RUNNING

leadi,game.ga_map

movcx,GM_HEIGHT

cld

xorax,ax

repstosw

movnextNO,0

callMB_gernicNext

callMB_gernicNext

calldrawNextBrick

callmoreBeautiful

;showsomestrings

movsi,offsetscoreStr

movdl,X_SCORE_STR

movdh,Y_SCORE_STR

movcx,6

callshowStr

movsi,offsetlevelStr

movdl,X_LEVEL_STR

movdh,Y_LEVEL_STR

movcx,6

callshowStr

movsi,offsetlevelDeltStr

movdl,X_adjustLevelDelt_STR

movdh,Y_adjustLevelDelt_STR

movcx,10

callshowStr

movsi,offsetusageStr

movdl,-GM_LEFT

movdh,-4

movcx,usageStrCNT

callshowStr

movsi,offsetusageStrEx

movdl,-GM_LEFT

movdh,-3

movcx,usageStrExCNT

callshowStr

movsi,offsetlinkToCoderStr

movdl,-GM_LEFT

movdh,-2

movcx,linkToCoderCNT

callshowStr

;showsomedigitials

callshowScore

callcalcLevel

callshowadjustLevelDelt

ret

GA_gameInitendp

;全局初始化,调用一次,设置DS,ES指向同一个数据段,程序运行过程中不再改变

setDSAndESprocfar

movax,MainData

movds,ax

moves,ax

ret

setDSAndESendp

;判断游戏区域(dl,dh)位置是否为空

;in:

dl-->x,dh-->y

;out:

flagregister

isPosNotEmptyproc

pushdx

pushbx

pushax

pushcx

pushdi

pushsi

movsi,curMB

movsi,(ManyBrickptr[si]).mb_bCnt

;ax--mask,第dl位置1

movax,1

movcl,dl

shlax,cl

leadi,game.ga_map

;map+2*dh

xorbh,bh

movbl,dh

shlbl,1

only_one_brick:

andax,[bx+di]

jeis_pos_empty_out

cmpsi,1

jneis_pos_empty_out

cmpbx,(2*GM_HEIGHT-2)

jeis_pos_empty_out_pre

addbx,2

jmponly_one_brick

;ensuretheresultiscorrect

is_pos_empty_out_pre:

cmpbx,0

is_pos_empty_out:

popsi

popdi

popcx

popax

popbx

popdx

ret

isPosNotEmptyendp

;判断游戏是否结束

isGameOverproc

pushbx

movbx,curMB

cmp(ManyBrickptr[bx]).mb_sPos.pos_bY,Y_START

jnestill_alive

;游戏的确结束了

movgame.ga_state,GS_OVER

calldoGameOver

still_alive:

popbx

ret

isGameOverendp

;游戏结束后,调用此过程,显示一些提示信息,待等用户下一步指示,重玩或退出

doGameOverproc

callclrScreen

callmoreBeautiful

movsi,offsetgameOverStr

movcx,45

movdl,X_GAME_OVER;x

movdh,Y_GAME_OVER;y

callshowStr

movax,game.ga_score

movcx,43

callAXModCX

andax,3

movdi,ax

shldi,1

movcx,judgeCnt[di]

movsi,judgeTable[di]

movdl,X_JUDGE_STR

movdh,Y_JUDGE_STR

callshowStr

moval,CHAR_BRICK

wait_for_restart:

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2