汇编语言菜单系统.docx
- 文档编号:30562884
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:25
- 大小:426.24KB
汇编语言菜单系统.docx
《汇编语言菜单系统.docx》由会员分享,可在线阅读,更多相关《汇编语言菜单系统.docx(25页珍藏版)》请在冰豆网上搜索。
汇编语言菜单系统
实训一光标漫游
⒈问题
在25行80列的显示屏内,通过按键"→、←、↑、↓〞来改变光标的位置,如按"→〞键则光标往右侧走一列,按"↑〞键则光标往上走一行的位置,最终通过"Esc〞完毕程序。
⒉边界问题
要处理好特殊情况:
①光标在第一行,再按"↑〞键时;②光标在第一列,再按"←〞键时;③光标在第25行,再按"↓〞键时;④光标在第80列,再按"→〞键时。
⒊边界问题处理
采用折返的方式:
①光标在第1行,再按"↑〞键时进到第25行;②光标在第1列,再按"←〞键时进到第80行;③光标在第25行,再按"↓〞键时进到第1行;④光标在第80列,再按"→〞键时时进到第1列。
⒋实验根底
1读键:
用int16h的0号功能调用
掌握扫描码和字符码的区别
Movah,0
Int16h
;返回AH=扫描码,AL=字符码
2定位光标:
用int10h的2号
3清屏:
用int10h的6号〔或7号〕功能调用
MOVAH,6
MOVBH,04h
MOVAL,0
MOVC*,0
MOVD*,184fh
INT10h
④相关键的扫描码和字符码
EnterKeyEQU1c0dh
EscKeyEQU010bh
UpCursorEQU4800h
LeftCursorEQU4b00h
RightCursorEQU4d00h
DownCursorEQU5000h
5.算法
do
{
定位光标
读键
if(al==特殊键)
{
if(ah==左光标键)
修正列值}
elseif(ah==右光标键)
{修正列值}
elseif(ah==上光标键)
{修正行值}
elseif(ah==下光标键)
{修正行值}
}
}
while(al!
=Esc)
6.实验步骤
运行"光标漫游例如.E*E〞了解需求。
①编一小程序获得特殊键"→、←、↑、↓〞"Esc、回车〞等的扫描码和Asc码值,并记录以备后用;
②写出光标漫游的算法〔保存,用类自然语言描述,用word,与同学、教师讨论算法的可行性与正确性〕;
③在②初步正确的根底上,编写汇编语言源程序;
④如发现算法问题,用调试器调试;
7.要点
光标如何根据所按的键跟随?
折返如何处理?
*=(*+1)%25;
8.该实验与大实验的关联性
请大家体会主菜单"实验蓝本.e*e〞的处理过程。
附件:
实验报告内容
①问题
②设计要点及算法
③源程序
④运行结果
⑤使用调试器状况和经历总结
⑥使用体会和总结
实训一光标漫游改良
根据跳跃表法〔另称跳转表,教材p180〕来改良光标漫游程序。
键:
"→、←、↑、↓〞、"Esc〞、"Enter〞、"ALT_*〞〔退出循环〕。
其中对"Esc〞、"Enter〞键暂不做任何处理。
1.掌握跳转表的原理
MenuJmpTbldwEnterkey,IsEnterKey
dwEscKey,IsESCKey
dwUpCursor,IsUpCursor
dwLeftCursor,IsLeftCursor
dwRightCursor,IsRightCursor
dwDownCursor,IsDownCursor
上述跳转表共6项,每项为:
键值〔扫描码+字符码〕、处理的入口地址
2.掌握跳转表的总控程序(入口地址为标号)
……
ContinueReadKey:
……
MOVB*,offsetMenuJmpTbl
MOVC*,6
YesNoKeyEqual:
cmpa*,[b*]
jeIsKeyEqual
addb*,4
loopYesNoKeyEqual
jmpContinueReadKey
IsKeyEqual:
movb*,[b*+2]
jmpb*
……
IsEnterKey:
…..
IsESCKey:
…..
3.掌握跳转表的总控程序(入口地址为子程序)
……
ContinueReadKey:
……
MOVB*,offsetMenuJmpTbl
MOVC*,6
YesNoKeyEqual:
cmpa*,[b*]
jeIsKeyEqual
addb*,4
loopYesNoKeyEqual
jmpContinueReadKey
IsKeyEqual:
movb*,[b*+2]
callb*
jmpContinueReadKey
……
IsEnterKeyproc
……;不能用无条件转移指令等跳出子程序
ret
IsEnterKeyendp
…..
IsESCKeyproc
…..
实训二色彩处理及方框显示
⒈问题
在显示屏显示各种形状的方框〔大小不一〕。
┬──┬┌───┐
││││
└──┘└───┘等
实验中可用1,2,3,4,…,9,0等来代替,如:
122222223
455555556
455555556
455555556
788888889
⒉实验根底
1注意颜色查看conio.c中的函数:
颜色名称
值
颜色名称
值
BLACK
0
DARKGRAY
8
BLUE
1
LIGHTBLUE
9
GREEN
2
LIGHTGREEN
10
CYAN
3
LIGHTCYAN
11
RED
4
LIGHTRED
12
MAGENTA
5
LIGHTMAGENTA
13
BROWN
6
YELLOW
14
LIGHTGRAY
7
WHITE
15
⒊实验步骤
①编写小程序,用int10h的0eh功能来显示字符串;
②写出显示方框的算法〔注意模块化〕;
③在②初步正确的根底上,编写汇编语言源程序;
④如发现算法问题,用调试器调试;
4完本钱实验的实验报告。
4.算法
ShowBo*(左上角坐标,右下角坐标,方框串,颜色)
{//显示第一行
//for显示中间行
//显示最后一行
}
ShowALineOfBo*(左上角坐标,宽度,方框子串,颜色)
{//定位光标
//设置颜色并显示第一字符
//for显示中间字符
//显示最后一字符
}
5.实验关键
先实现ShowALineOfBo*子程序,编程时考虑模块化的概念,处理参数的传递方法〔先采用变量或存放器的方式来传送〕。
参考以下案例:
bo*strdb'123'
….
movah,0eh
movbl,0fh
movbh,0
moval,bo*str
int10h
movc*,10
moval,bo*str+1
showrepchar:
int10h
loopshowrepchar
moval,bo*str+2
int10h
注意上述代码和算法的关系。
6.直接写屏来显示的原理和方法
①对显示缓冲区的简单介绍
②对字符属性字节的简单介绍
③一个简单的例子
④直接写屏的案例
movdi,0b800h
moves,di
*ordi,di;di=0,表示是0行0列的位置,如要显示在(5,8)的位置,di该何值?
movsi,offsetbo*str
movah,0fh
lodsb
stosw
movc*,10
lodsb
repstosw
lodsb
stosw
7.直接写屏的方框显示算法
ShowBo*(左上角坐标,右下角坐标,方框串,颜色)
{//根据左上角坐标计算显示缓冲区地址,用子程序定义
//显示第一行
//for显示中间行
//显示最后一行
}
※可用+160的方法来处理下一行的起始位置,编程时用进栈和退栈指令来保存和复原
ShowALineOfBo*(左上角坐标的起始地址,宽度,方框子串,颜色)
{
//设置颜色并显示第一字符
//for显示中间字符
//显示最后一字符
}
8.参数表的标准传递方式
ShowBo*(左上角坐标,右下角坐标,方框串,颜色)
C语言参数传递模型:
把参数自右向左压入栈;在函数执行时用相应的参数数据。
子程序的参数入栈:
例如
Mova*,颜色
Pusha*
Mova*,方框串地址
Pusha*
Mova*,右下角坐标
Pusha*
Mova*,左下角坐标
Pusha*
…
showBo*proc
;子程序里代码
Movbp,sp
;[bp+2]左下角坐标
;[bp+4]右下角坐标
;[bp+6]串地址
;[bp+8]颜色
……
ret8
showBo*Endp实训三主菜单的显示与选择
⒈问题
在屏幕上显示以下菜单,并能通过"→、←、↑、↓〞来切换菜单项。
如初始显示为:
当按"→〞键时,变成:
再按"→〞键时,变成:
系统的先期实现按以下约定实施:
"Enter〞确认菜单项或弹出子菜单;
"ESC〞返回子菜单;
"→、←〞主菜单项间切换;
"↑、↓〞子菜单项间切换;
完成上述功能后,再对相应的按键进展功能的扩展。
⒉实验根底
本实验是实验一加颜色处理的方法来实现,所以本次实验的根底大家都具备。
运行"主菜单演示.e*e〞体会编程。
⒊实验原理
如何来实现菜单项的切换是本实验的技巧。
假定我们用一变量mi来指向当前选中的菜单,当按"→〞键时,我们用"未选中的颜色〞来定位重写"File〞的串,使菜单变成:
然后是按键处理后,mi修正为1,然后用"选中的颜色〞定位重写"Edit〞,
变成上图的效果,实现了菜单项的动态切换。
⒋实验步骤
①在word上写出算法〔其中主菜单的字符串数据放在数组中〕。
②思考……
③提问
④算法正确后再编写程序。
⒌主菜单的显示算法
实训四菜单数据的组织
⒈问题
看实例"实验蓝本.e*e〞,思考菜单数据如何组织?
数据的组织与菜单显示之间怎么关联?
⒉菜单的逻辑构造图
⒊数据的组织构造
//菜单构造体定义
MenuStrustruc
SubMenuCountdb";子菜单的数目
SubMenuWidthdb";子菜单的宽度
SubMenuAddrdw";子菜单数据构造地址
MenuStrWidthdb";菜单项字符串长度
MenuStrAddrw";菜单项的字符串地址
MenuStruends
⒋菜单数据的组织
看"Menu2021.asm〞
⒌理解菜单数据组织与程序的关系
⒍改良实训练三
①掌握构造体变量和指针的使用;
②在一循环中用构造体变量或指针来访问相关参数;
③在循环中参加打印字符串语句,显示出主菜单;
④参加颜色等,实现主界面。
实训五菜单系统的设计
整个菜单系统的设计需要进一步抽象。
设计时要考虑扩展性和通用性的问题:
菜单数据的改变,如我们的实例中只有3层菜单,如果把菜单数据增加到4、5等层次菜单时,你所编写的程序代码在只允许修改菜单数据,而不允许修改所有的函数的情况下,你的设计是否能到达此目标?
要实现上述目标,必须对处理过程进展抽象。
菜单系统总体上应该如此实施:
①显示主菜单;②读键〔暂定有效键为"→、←、↑、↓、Esc、Enter〞〕;③处理有效键。
④反复执行②③。
特别要注意整个程序中只有一处读键的地方。
由于菜单系统选择的层次性,我们必须对菜单项选择择的〔中间〕过程进展有效保存,以便回溯。
如当我们进入主菜单项的"Options〞→"piler〞→"piler〞的子菜单,当我们用"Esc〞键时可以回退到"piler〞状态,从"piler〞还可以回退到"Options〞状态。
为有效管理这种选择状态,我们必须对选择状态加以保存。
我们采取以下构造体来保存选择的历史信息(C语言):
typedefstructMenuSelectStru{
ShortIntMenuInde*,MenuTotal;//选择菜单中的哪项
MenuItemStru*MenuAddr;//对应主菜单/子菜单的数据构造地址
PCHAR_INFOAddrOfSaveTe*t;//备份下拉菜单区域的空间
boolPullDownMenu;//下拉菜单有否显示
ShortIntleft,top,right,bottom;
};
也可考虑用以下历史构造:
〔把left,top,right,bottom内容放入AddrOfSaveTe*t指向的空间中〕
HistoryStrustruc
MenuInde*db0;选择菜单中的哪项
MenuTotaldb0;菜单的项数
MenuAddrdw0;对应主菜单/子菜单的数据构造地址
AddrOfSaveTe*tdw0;备份下拉菜单区域的空间
PullDownMenudb0;下拉菜单有否显示
HistoryStruends
考虑到本实验的最大菜单级数为三级,我们可定义含3个元素的数组来保存历史的选择信息〔如果考虑3级以上,则应该把数组的元素个数适当加大〕。
//选择的历史缓冲区
CHAR_INFOSecondSave[300],FirstSave[300];
MenuSelectStruHis[3]={{0,8,MainMenu,false,0,0,0,0},
{0,0,0,FirstSave,false,0,0,0,0},
{0,0,0,SecondSave,false,0,0,0,0}};
有了选择的历史缓冲区,可以提高我们的抽象级别:
该层菜单的选中项 该层菜单的总数 该层菜单的首地址
MenuInde*
MenuTotal
MenuAddr
…
0
8
MainMenu
0
1
2
3
4
MenuLayer指向当前菜单项选择择的层次
当我们操作菜单时,可以围绕"选择的历史缓冲区〞来管理即可,如:
当我们在主菜单的选择时定位到"Options〞时,历史数据为:
MenuInde*
MenuTotal
MenuAddr
…
5
8
MainMenu
当拉下"Options〞的子菜单进入到"子菜单的选择〞时,历史数据为:
MenuInde*
MenuTotal
MenuAddr
…
5
8
MainMenu
0
5
OptSubM
当在"Options〞的子菜单下操作时,我们改变MenuInde*的值即可,如选中"Options〞子菜单下的"Linker〞项,MenuInde*应该为1:
MenuInde*
MenuTotal
MenuAddr
…
5
8
MainMenu
1
5
OptSubM
His[Layer].MenuAddr:
表示主〔或子〕菜单数组的首地址
对应MainMenu[*].SubMenuItemAddr变成
His[Layer].MenuAddr[His[Layer].MenuInde*].SubMenuAddr
此时Layer=0;
如何得到子菜单的起始显示列值?
答:
MainMenuCol[His[0].MenuInde*]
显示区备份与复原编程有关函数〔在conio.c中〕:
获得显示区的属性信息:
voidgette*tinfo(structte*t_info*_r)
把_source指向的数组的内容复原到区域〔_left,_top〕、〔_right,_bottom〕:
voidputte*t(int_left,int_top,int_right,int_bottom,PCHAR_INFO_source)
把显示区域〔_left,_top〕、〔_right,_bottom〕中的内容备份到_target指向的数组:
voidgette*t(int_left,int_top,int_right,int_bottom,PCHAR_INFO_target)
实训六浏览DbaseⅢ表数据
⒈问题
了解DbaseⅢ的表构造,掌握一种通用的数据组织原理,并把数据在工作区中显示。
⒉实验根底
①了解DbaseⅢ的表构造及定义;
②对照DbaseⅢ构造用二进制编辑器Fle*He*.e*e软件来查看其物理组织原理;
③掌握高级语言中的"int〞等类型的数据组织方式〔注意高字节放在高地址〕;
④用小程序分步读出文件头、字段信息等;
⑤最后实施表数据的浏览。
附件:
DBF文件格式分析
DBF数据表文件的构造分析:
DBF文件由两局部组成,
第一局部是构造描述,即文件头信息;共32个字节〔0~31〕
第二局部是表本身的内容,该局部又分为两个局部:
前一局部是表的构造说明,共32个字节具体的内容见下表1
后一局部是字段描述区,从第32个字节开场到十六进制完毕字符0*0D。
具体包括内容见表2
解读:
低字节在前,所以要取字段总数时,应该用如下方法:
记录总数 = 第4个字节+2561次方*第5字节+2562*第6字节+2563*第7字节
注意:
字段名 以ASCII码方式存放,最大长度是10个字符,假设字段名长度少于10个字符则以空字符(0*00)填充
字段类型 以ASCII码方式存放,1个字符,其值为
Fieldtype:
C – Character
Y – Currency
N – Numeric
F – Float
D – Date
T – DateTime
B – Double
I – Integer
L – Logical
M –Memo
G –General
C – Character(binary)
M – Memo(binary)
P – Picture
+ – Autoincrement(dBaseLevel7)
O – Double(dBaseLevel7)
– Timestamp(dBaseLevel7)
DBF数据表文件的构造完毕标志为"0*0D",占1个字节。
对于VFP表文件从"0*0D"所在的字节开场的263B用于描述自由表或数据库表的相关信息〔假设为自由表则取值全为零〕。
其VFP表文件长度=32〔文件头〕+32*字段个数+1〔完毕标志〕+263。
然后是数据局部记录1、记录2……记录n
各记录均为定长格式,以ASCII码方式顺序存放。
每个记录的第一个字节是删除标志,假设记录被删除,则该字节为0*2A即"*";否则为0*20即空格。
各记录间无分隔符
整个文件的完毕标志为0*1A,位于最后一个记录之后的一个字节中。
struct dbf_head { /* DBF文件头构造 */ char vers; /* 版本标志*/ unsigned char yy,mm,dd; /* 最后更新年、月、日 */ unsigned long no_recs; /* 文件包含的总记录数 */ unsigned short head_len,rec_len; /* 文件头长度,记录长度 */ char reserved[20]; /* 保存 */ }; struct field_element{ /* 字段描述构造 */ char field_name[11]; /* 字段名称 */ char field_type; /* 字段类型 */ unsigned long offset; /* 偏移量 */ unsigned char field_length; /* 字段长度 */ unsigned char field_decimal; /* 浮点数整数局部长度 */ char reserved1[2]; /* 保存 */ char dbaseiv_id; /* dBASE IV work area id */ char reserved2[10]; /* char production_inde*; }; /************************************************************************************ MENTS:
DBF文件的总体格式a.数据记录局部,紧随构造描述局部,以ASCII码方式顺序存放,完毕标志为1AH(即 文件完毕标志),每条记录的首字节为删除标志,20H表示有效,2AH表示已被删除, 字段值间无分隔符,记录亦无完毕标记.b.构造描述局部,位于文件首部,以二进制方式存放,完毕标志为0DH.长度 为32*(数据库的字段个数+1(即库整体描述))+1(0DH完毕标志) ************************************************************************************/
#include
//DBF 文件头构造//即库整体描述表,共32个字节typedef struct tagDBFFILEHEADER{unsigned chardfMark;//0*03h 或 0*80h(有MEMORY字段)0unsigned chardfYear,dfMmonth,dfDay;//依次为年月日,二进制1-3unsigned longdfRecordCount;//总记录个数,低位字节在前4-7unsigned shortdfHeaderLength;//文件头长度=第9字节值*256+第8字节值8-9unsigned shortdfRecordLength;//记录长度=第11字节值*256+第10字节值10-11unsigned chardfReserved[20];//保存12-31}DBFFILEHEADER;
//DBF 字段构造//即字段描述表,32个字节/字段typedef struct tagDBFINFOHEADER{unsigned chardiFieldName[10];//字段名称,ASCII码0-9unsigned chardiReserved1;//保存字节10unsigned chardiFieldType;//字段类型,CDNL等A
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 菜单 系统