汇编语言菜单系统.docx

上传人:b****8 文档编号:30562884 上传时间:2023-08-16 格式:DOCX 页数:25 大小:426.24KB
下载 相关 举报
汇编语言菜单系统.docx_第1页
第1页 / 共25页
汇编语言菜单系统.docx_第2页
第2页 / 共25页
汇编语言菜单系统.docx_第3页
第3页 / 共25页
汇编语言菜单系统.docx_第4页
第4页 / 共25页
汇编语言菜单系统.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

汇编语言菜单系统.docx

《汇编语言菜单系统.docx》由会员分享,可在线阅读,更多相关《汇编语言菜单系统.docx(25页珍藏版)》请在冰豆网上搜索。

汇编语言菜单系统.docx

汇编语言菜单系统

实训一光标漫游

⒈问题

在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

DARKGRAY

BLUE

LIGHTBLUE

GREEN

LIGHTGREEN

10

CYAN

LIGHTCYAN

11

RED

LIGHTRED

12

MAGENTA

LIGHTMAGENTA

13

BROWN

YELLOW

14

LIGHTGRAY

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  #include  #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

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

当前位置:首页 > 考试认证 > 交规考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1