1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,#,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,#,汇编语言程序设计,吴 向 军,中山大学计算机科学系,第,6,章 程序的基本结构,6.1.1,段的定义,在定义段时,每个段都有一个段名。在取段名时,要取一个具有一定含义的段名。段定义的一般格式如下:,段名,SEGMENT ,对齐类型,组合类型,类别,;,段内的具体内容,段名,ENDS,其中:“段名”必须是一个合法的标识符,前后二个段名要相同。可选项“对齐类型”、“组合类型”和“类别”的说明作用请见,6.3,节中的叙述。,段
2、的长度是指该段所占的字节数:,如果段是数据段,则其长度是其所有变量所占字节数的总和;,如果段是代码段,则其长度是其所有指令所占字节数的总和。,在通常情况下,一个段的长度不能超过,64K,,在,80386,及其以后系统的保护方式下,段基地址是,32,位,段的最大长度可达,4G,。,6.1,源程序的基本组成,第,6,章 程序的基本结构,一个数据段的定义例子:,DATA1 SEGMENT,word1DW1,9078H,?,byte1DB21,World,DD12345678H,DATA1 ENDS,一个代码段的例子:,CODE1SEGMENT,MOVAX,DATA1;,把数据段,DATA1,的段值送
3、,AX,MOVDS,AX;,把,AX,的值送给,DS,,即:,DS,存储数据段的段值,MOVAX,4C00H,INT21H;,调用,DOS,功能,结束程序的运行,CODE1ENDS,第,6,章 程序的基本结构,6.1.2,段寄存器的说明语句,在汇编语言源程序中可以定义多个段,每个段都要与一个段寄存器建立一种对应关系。建立这种对应关系的说明语句格式如下:,ASSUME,段寄存器名,:,段名,段寄存器名,:,段名,其中:段寄存器是,CS,、,DS,、,ES,、,SS,、,FS,和,GS,,段名在段定义语句说明。,例如,,ASSUME CS:CODE1,DS:DATA1,说明了:,CS,对应于代码段
4、,CODE1,,,DS,对应于数据段,DATA1,。,在,ASSUME,语句中,还可以用关键字,NOTHING,来说明某个段寄存器不与任何段相对应。下面语句说明了段寄存器,ES,不与某段相对应。,ASSUME ES:NOTHING,在通常情况下,代码段的第一条语句就是用,ASSUME,语句来说明段寄存器与段之间的对应关系。,在代码段的其它位置,还可以用另一个,ASSUME,语句来改变前面,ASSUME,语句所说明的对应关系,这样,代码段中的指令就用最近的,ASSUME,语句所建立的对应关系来确定指令中的有关信息。,第,6,章 程序的基本结构,例,6.1,:汇编语言段及其段说明语句的作用。,DA
5、TA1SEGMENT;,定义数据段,DATA1,word1DW5678h,byte1DB“ABCDEFG”,DATA1ENDS,DATA2SEGMENT;,定义数据段,DATA2,word2DW1234h,word3DW9876h,DATA2ENDS,DATA3SEGMENT;,定义数据段,DATA3,byte2DB?,DATA3ENDS,第,6,章 程序的基本结构,CODE1SEGMENT;,编写代码段,CODE1,ASSUME CS:CODE1,DS:DATA1,ES:DATA2;,MOVAX,DATA1;,MOVDS,AX;,MOVAX,DATA2;,MOVES,AX;,MOVAX,wo
6、rd1;,访问段,DATA1,中的字变量,word1,MOVword2,AX;,访问段,DATA2,中的字变量,word2,ASSUME DS:DATA3,ES:NOTHING;,MOVAX,DATA3,MOVDS,AX,MOVBL,byte2;,访问段,DATA3,中的变量,byte2,MOVAX,4C00H;,INT21H;,CODE1ENDS,第,6,章 程序的基本结构,6.1.3,堆栈段的说明,在源程序中,可用以下方法来定义堆栈段。,方法,1,:,Stack1SEGMENT,DB256 DUP(?);256,是堆栈的长度,可根据需要进行改变,TOPLABEL WORD,Stack1EN
7、DS,由于堆栈是按地址从大到小的存储单元顺序来存放内容的,所以,在堆栈存储单元说明语句之后,再说明一个栈顶别名,这样,对,SP,的赋值就很方便。,在源程序中,还要添加如下程序段,才能把段,Stack1,当作堆栈段来使用。,ASSUME SS:STACK1;,可在代码段的段指定语句中一起说明,CLI;,禁止响应可屏蔽中断,MOVAX,STACK1,MOVSS,AX,MOVSP,offset TOP;,给堆栈段的栈顶寄存器,SP,赋初值,STI;,恢复响应可屏蔽中断,第,6,章 程序的基本结构,方法,2,:,STACK1SEGMENT STACK;,定义一个堆栈段,其段名为,STACK1,DB25
8、6 DUP(?),STACK1ENDS,上述段定义说明了该段是堆栈段,系统会自动把段寄存器,SS,和栈顶寄存器,SP,与该堆栈段之间建立相应的关系,并设置其初值,而不用在代码段对它们进行赋值。,除了以上二种方法外,还有一种更简洁的方法来定义堆栈段,有关内容请见第,6.4.2,节中的叙述。,第,6,章 程序的基本结构,6.1.4,源程序的结构,例,6.2,:在屏幕上显示字符串“,Hello,World.”,STACK1SEGMENT STACK;,定义堆栈段,STACK1,DB 256 DUP(?),STACK1ENDS,DATA1SEGMENT;,定义数据段,DATA1,MSGDB“Hello
9、,World.$”,DATA1ENDS,CODE1SEGMENT;,编写代码段,CODE1,ASSUME CS:CODE1,DS:DATA1,START:MOVAX,DATA1,MOVDS,AX,MOVDX,offset MSG,MOVAH,9,INT21H;,中断,21H,的,9H,号功能,显示,DS:DX,指向的字符串,MOVAX,4C00H,INT21H,CODE1ENDS,ENDSTART;,源程序的结束语句,伪指令,END,表示源程序到此为止,汇编程序对该语句之后的任何内容都不作处理,所以,通常情况下,伪指令,END,是源程序的最后一条语句。,伪指令,END,后面可附带一个在程序中已
10、定义的标号,该标号指明程序的启动位置。,如果源程序是一个独立的程序或主模块,那么,伪指令,END,后面一定要附带一个标号;如果源程序仅是一个普通模块,那么,其,END,后面就一定不能附带标号。,第,6,章 程序的基本结构,6.2.1,顺序结构,在学习高级语言程序设计时,我们知道了程序的三大主要结构:顺序结构、分支结构和循环结构。在汇编语言的源程序也同样有此三大结构,所不同的是它们的表现形式不同。用高级语言编写程序时,由于不使用“转移语句”而使这三种结构清晰明了。,6.2,程序的基本结构,顺序结构是最简单的程序结构,程序的执行顺序就是指令的编写顺序,所以,安排指令的先后次序就显得至关重要。另外,
11、在编程序时,还要妥善保存已得到的处理结果,为后面的进一步处理直接提供前面的处理结果,从而避免不必要的重复操作。,例,6.3,编写程序段,完成下面公式的计算。,A(X-Y+24)/Z,的商,,B(X-Y+24)/Z,的余数,其中:变量,X,和,Y,是,32,位有符号数,变量,A,,,B,和,Z,是,16,位有符号数。,第,6,章 程序的基本结构,6.2.2,分支结构,例,6.5,已知字节变量,CHAR1,,编写一程序段,把它由小写字母变成大写字母。,例,6.6,编写一程序段,计算下列函数值。其中:变量,X,和,Y,是有符号字变量。,例,6.7,把下列,C,语言的语句改写成等价的汇编语言程序段,(
12、,不考虑运算中的溢出,),。,If(a+b 0,else a=21;,其中:变量,a,、,b,和,c,都是有符号的整型,(int),变量。,第,6,章 程序的基本结构,分支伪指令的具体格式如下:,格式,1,:,.IF condition,指令序列,.ENDIF,格式,2,:,.IF condition,指令序列,1,.ELSE,指令序列,2,.ENDIF,格式,3,:,.IF condition1,指令序列,1,.ELSEIF condition2,指令序列,2,.ENDIF,其中:条件表达式“,condition”,的书写方式与,C,语言中条件表达式的书写方式相似,也可用括号来组成复杂的条件
13、表达式。,第,6,章 程序的基本结构,条件表达式中可用的操作符有:,=(,等于,),、,!=(,不等,),、,(,大于,),、,=(,大于等于,),、,(,小于,),、,lib/?,该命令的显示结果如右图所示。,7.6.1,建立库文件命令,7.6,子程序库,第,7,章 子程序和库,二、,Windows,系统,第,7,章 子程序和库,假设现有目标文件,sub1.obj,、,sub2.obj,和,sub3.obj,,要用它们建立库文件,mylib.lib,。可用下列方法来建立该库文件:,方法,1,:所有目标文件都准备好了,可一次性把它们加入到库文件中,lib mylib+sub1+sub2+sub
14、3,方法,2,:随着目标文件的逐个生成,而依次把它们加入到库文件中,lib mylib+sub1,lib mylib+sub2,lib mylib+sub3,假如源文件,sub3.asm,已修改,并也生成了新的目标文件,sub3.obj,,这时,可用下面命令来实现替换:,lib mylib -+sub3,当提示目标库文件名,(Output library),时,可按“回车”用默认的原库文件名。,如果想查看库文件,mylib.lib,中文件的大小和存放的先后次序,可用下列命令:,lib mylib,list;,把库文件,mylib.lib,中的文件结构生成到文件,list,中,type list
15、,7.6.2,建立库文件举例,第,7,章 子程序和库,当开发一个功能较强、关系较复杂的应用程序时,其执行文件常常由多个目标文件,(,模块,),连接而成的。各模块之间无疑会存在着相互调用、相互访问数据单元等内在联系。,为了解决描述各模块之间的联系,汇编语言提供了二条伪指令,PUBLIC,和,EXTRN,,它们的作用说明变量、过程和函数是“全局的”或“外部的”。,这二条伪指令的具体用法和含义如下:,1.,伪指令,PUBLIC,伪指令,PUBLIC,是用来说明:当前模块中哪些标识符是能被其它模块引用的公共标识符。其说明的一般格式如下:,PUBLIC,标识符,1,标识符,2,其中:“标识符”可以是变量
16、名、过程名和程序标号,标识符之间要用逗号分开。,上面说明语句说明了标识符,1,、标识符,2,等是公共标识符,可以被其它模块引用。在一个模块中,可用多条,PUBLIC,伪指令来说明公共标识符。,7.6.3,库文件的应用,第,7,章 子程序和库,2.,伪指令,EXTRN,伪指令,EXTRN,是用来说明:在当前模块所使用的标识符中,哪些标识符是已在其它模块中被定义为指定类型的标识符。如果当前模块使用了其它模块的标识符,而对它又不加以说明的话,那么,汇编程序将会给出下列出错信息:,error nnnnn:undefined symbol:XXXXXX,伪指令,EXTRN,的一般说明格式如下:,EXTR
17、N,标识符,1:,类型,1,标识符,2:,类型,2,其中:“标识符”和“类型”之间要用冒号“,:”,连接。,上面语句说明了标识符,1,、标识符,2,等是外部标识符,它们在其它模块中已被分别定义为类型,1,、类型,2,等,该类型说明符可以是:,NEAR,、,FAR,、,BYTE,、,WORD,、,DWORD,等之一。,在一个模块中,可用多条,EXTRN,伪指令来说明本模块所引用的外部标识符。,注意:伪指令,EXTRN,中所说明的标识符必须在其定义的模块中被,PUBLIC,伪指令说明为公共标识符,并且其说明的标识符类型要与该标识符在定义是的类型相一致,否则,要么不能生成其可执行文件,要么其执行文件
18、不能正确运行。,第,7,章 子程序和库,程序员在编写程序时,通常采用模块化的思想来组织源程序:把各类子程序分别编写在不同的源程序中,在各源程序中说明所用到的、在其它模块中已定义的子程序,或说明本模块所定义的子程序可被其它模块调用。这样就可以分别汇编它们而得到其相应的目标文件,在有了这些目标文件后,程序员就可用不同的方法来生成最终的可执行目标文件。,方法,1,:直接连接目标文件而生成可执行文件,这种方法简单、方便,也是常用的一种方法,但在连接时,,LINK,程序会把目标文件中的所有代码都嵌入到执行文件中,从而使得:包含在某目标文件中、但并没有被调用的子程序代码也出现在执行文件中。这种情况无疑增加
19、了执行文件的字节数。,7.6.4,库文件的好处,第,7,章 子程序和库,方法,2,:采用子程序库的方法,库文件可以把它看成是子程序的集合。库文件中存储着子程序名、子程序的目标代码以及连接所需要的重定位信息。,当某目标文件与库文件相连接时,,LINK,程序只把目标文件所用到的子程序从库文件中找出来,并合并到最终的可执行文件中,而不是把库中所含的全部子程序都纳入最后的可执行文件。,对照方法,1,和,2,可知:用库文件来存储子程序可生成较短的执行文件。,第,8,章 输入输出和中断,输入输出是一个完整应用程序的重要组成部分,是交互式应用程序不可缺少的组成部分。在高级语言编程时,程序员可直接用输入输出语
20、句来完成键盘输入、屏幕显示或打印输出等需求,而无需关心这些输入输出语句是如何实现的。但汇编语言是与机器有关的程序设计语言,要编写出具有输入输出功能的代码段就必须清楚,CPU,为输入输出提供了哪些指令,或计算机系统提供了哪些可直接使用的功能调用。,8.1.1 I/O,端口地址,8.1,输入输出的基本概念,I/O,端口是,CPU,与输入输出设备的交换数据的场所。通过,I/O,端口,处理机可以接受从输入设备输入的信息,也可向输出设备发送信息。,在计算机系统中,用不同的数字给各类,I/O,端口进行编号,这种,I/O,端口的编号就称为,I/O,端口地址。,第,8,章 输入输出和中断,在,Intel,公司
21、的,CPU,家族中,,I/O,端口的地址空间可达,64K,,即可有,65536,个字节端口,或,32768,个字端口。这些地址不是内存单元地址的一部分,不能用普通访问内存指令来读取其信息,要用专门的,I/O,指令才能访问它们。虽然,CPU,提供了很大的,I/O,地址空间,但目前大多数微机所用的端口地址都在,03FFH,范围之内,其所用的,I/O,地址空间只占整个,I/O,地址空间的很小部分。,表,8.1,几个重要的,I/O,端口地址,端口地址,端口名称,端口地址,端口名称,020H023H,中断屏蔽寄存器,378H37FH,并行口,LPT2,040H043H,时针,/,计数器,3B0H3BBH
22、,单色显示器端口,060H,键盘输入端口,3BCH3BFH,并行口,LPT1,061H,扬声器,(0,,,1,位,),3C0H3CFH,VGA/EGA,200H20FH,游戏控制口,3D0H3DFH,CGA,278H27FH,并行口,LPT3,3F0H3F7H,磁盘控制器,2F8H2FFH,串行口,COM2,3F8H3FFH,串行口,COM1,第,8,章 输入输出和中断,8.1.2 I/O,指令,由于,I/O,端口地址和内存单元地址是相互独立的,这些端口地址不能用普通的访问内存指令来访问其信息。,输入指令,IN,输入指令,IN,的一般格式如下:,INAL/AX,PortNo/DX,该指令的作用
23、是从端口中读入一个字节或字,并保存在寄存器,AL,或,AX,中。如果某输入设备的端口地址在,0255,范围之内,那么,可在指令,IN,中直接给出,否则,要把该端口地址先存入寄存器,DX,中,然后由,DX,来给出其端口地址。,例如:,INAL,60H;,从端口,60H,读入一个字节到,AL,中,INAX,20H;,把端口,20H,、,21H,按“高高低低”组成的字读入,AX,MOVDX,2F8H,INAL,DX;,从端口,2F8H,读入一个字节到,AL,中,INAX,DX;,把端口,2F8H,、,2F9H,按“高高低低”组成的字读入,AX,第,8,章 输入输出和中断,输出指令,OUT,输出指令,
24、OUT,的一般格式如下:,OUTPortNo/DX,AL/AX,该指令的作用是把寄存器,AL,或,AX,的内容输出到指定端口。如果某输出设备的端口地址在,0255,范围之内,那么,可在指令,OUT,中直接给出,否则,要把该端口地址先存入寄存器,DX,中,然后在指令中由,DX,来给出其端口地址。,例如:,OUT61H,AL;,把,AL,的内容输出到端口,61H,中,OUT20H,AX;,把,AX,的内容输出到端口,20H,、,21H,中,MOVDX,3C0H,OUTDX,AL;,把,AL,的内容输出到端口,3C0H,中,OUTDX,AX;,把,AX,的内容输出到端口,3C0H,、,3C1H,中,
25、第,8,章 输入输出和中断,8.2.1,中断的基本概念,8.2,中断,1.,中断和中断源,CPU,在执行程序时,是否响应中断要取决于以下三个条件能否同时满足:,(1),、有中断请求,(2),、允许,CPU,接受中断请求,(3),、一条指令执行完,下一条指令还没有开始执行,条件,(1),是响应中断的主体。除用指令,INT,所引起的软件中断之外,其它中断请求信号是随机产生的,程序员是无法预见的。,程序员可用程序来控制条件,(2),的满足与否,即用指令,STI,和,CLI,来控制,CPU,是否响应可屏蔽的外部中断。但对于不可屏蔽中断和内部中断,程序员是无法控制它们的,,CPU,一定会执行这些中断的中
26、断服务程序。,第,8,章 输入输出和中断,2.,中断向量表和中断服务程序,中断向量表是一个特殊的线性表,它保存着系统中所有中断服务程序或系统参数的入口地址,(,偏移量和段地址,),。在微机系统中,该向量表有,256,个元素,每个元素占,4,个字节,总共占,1K,个字节。,右图中的“偏移量”和“段地址”是指该中断服务程序入口单元的“偏移量”和“段地址”。从图中不难看出:若中断号为,n,,则在中断向量表中存储该中断服务程序入口地址的单元地址为:,4n,。,第,8,章 输入输出和中断,表,8.2,部分常用的中断号及其含义,中断号,含义,中断号,含义,0,除法出错,8,定时器,1,单步,9,键盘,2,
27、非屏蔽中断,A,未用,3,断点,B,COM2,4,溢出,C,COM1,5,打印屏幕,D,硬盘,(,并行口,),6,未用,E,软盘,7,未用,F,打印机,第,8,章 输入输出和中断,8.2.2,引起中断的指令,1,、中断指令,INT,中断指令,INT,的一般格式如下:,INT Imm,其中:立即数,Imm,是一个,00FFH,范围内的整数。,指令执行的步骤:,把标志寄存器压栈,清除标志位,IF,和,TF,;,把段寄存器,CS,的内容压栈,并把中断服务程序入口地址的高字部分送,CS,;,把指针寄存器,IP,的内容压栈,并把中断服务程序入口地址的低字部分送,IP,;对,80386,及其以后的,CPU
28、,,对,16,位段,压,16,位,IP,;对,32,位段,压,32,位,EIP,。,在该指令执行完后,,CPU,将转去执行中断服务程序。由于有了指令,INT,,程序员就能为满足某种特殊的需要,在程序中有目的地安排中断的发生,也就是说,该中断不是随机产生的,而是完全受程序控制的。,第,8,章 输入输出和中断,2,、溢出指令,INTO,当标志位,OF,为,1,时,引起中断。该指令格式如下:,INTO,该指令影响标志位:,IF,和,TF,。,第,8,章 输入输出和中断,8.2.3,中断返回指令,当一个中断服务程序执行完毕时,,CPU,将恢复被中断的现场,返回到被中断的程序中。为实现此功能,指令系统提
29、供了一条专用的中断返回指令。该指令的格式如下:,IRET/IRETD,该指令执行的过程基本上是,INT,指令的逆过程,具体如下:,从栈顶弹出内容送入,IP,;,再从新栈顶弹出内容送入,CS,;,再从新栈顶弹出内容送入标志寄存器;,对,80386,及其以后的,CPU,,指令,IRETD,从栈顶弹出,32,位内容送入,EIP,。,第,8,章 输入输出和中断,8.2.4,中断和子程序调用,中断和子程序调用之间有其相似和不同之处。它们的工作过程非常相似,即:暂停当前程序的执行,转而执行另一程序段,当该程序段执行完时,,CPU,都自动恢复原程序的执行。,中断和子程序调用在实现方面的主要差异:,子程序调用
30、是程序员在编写源程序时事先安排好的,是可知的,而中断是由中断源根据自身的需要产生的,是不可预见的,(,用指令,INT,引起的中断除外,),;,子程序调用是用,CALL,指令来实现的,但没有调用中断的指令,只有发出中断请求的事件,(,指令,INT,是发出内部中断信号,不要理解为调用中断服务程序,),;,子程序的返回指令是,RET,,而中断服务程序的返回指令是,IRET/IRETD,;,在通常情况下,子程序是由应用系统的开发者编写的,而中断服务程序是由系统软件设计者编写的。,第,8,章 输入输出和中断,8.3,中断功能的分类,汇编语言程序员常用的这类中断有:,DOS,功能调用,(INT 21H),
31、、,BIOS,中断、硬件和外设的中断等。,在用户程序中,若直接通过端口来操作硬件或外设,那么,其处理过程没有额外的多余工作,处理速度显然是最快的,但这样做,无疑使用户程序具有了很大的局限性。硬件环境的改变将直接影响程序的正常运行。,若用户程序通过调用,DOS,功能来实现其所需功能,那么,应用程序与低层硬件相距较远,操作最终的对象需要经过中间环节,处理速度肯定受到一定的损失,但这种应用程序适应性强,应用范围广,对硬件的依赖性最小。,由于,BIOS,介于,DOS,和具体硬件之间,所以,调用,BIOS,的功能是一个很好的折中方案。程序员可在以下三种情况下考虑使用,BIOS,的功能:,1),、,BIO
32、S,提供的功能,而,DOS,没有提供该功能的情况;,2),、不能利用,DOS,功能调用的情况,(,可能因为某些具体应用的限制,),;,3),、基于处理速度的考虑,需要绕过,DOS,层的情况。,综上所述,可以归纳出如下结论:使用中断的层次越高,它与硬件设备相关程度就越低,处理速度也就越低,但用户程序的适用范围较广。反之也然。,第,8,章 输入输出和中断,8.3.1,键盘输入的中断功能,例,8.1,用键盘最多输入,10,个字符,并存入内存变量,Buff,中,“,CR”,键结束输入。,解:,1,、方法,1,.MODEL SMALL,CREQU0DH;,定义“回车”键的符号名,.DATA,BuffDB
33、10 DUP(?),.CODE,.STARTUP,MOVCX,0AH,LEABX,Buff,.REPEAT,MOVAH,0H,INT16H;,用,BIOS,中的中断功能,.BREAK .IF AL=CR,MOVBX,AL,INCBX,.UNTILCXZ,.EXIT0,END,第,8,章 输入输出和中断,例,8.1,用键盘最多输入,10,个字符,并存入内存变量,Buff,中,“,CR”,键结束输入。,解:,2,、方法,2,.MODEL SMALL,.DATA,BuffDB 10,?,10 DUP(?);,注意缓冲区的定义方式,.CODE,.STARTUP,LEADX,Buff,MOVAH,0AH
34、,INT21H;,用,DOS,中的功能调用,.EXIT0,END,第,8,章 输入输出和中断,8.3.2,屏幕显示的中断功能,1,、文本显示方式,文本显示方式是指以字符为最小单位的显示方式,每个字符都是以矩形块形式显示的。,在常用的文本显示模式,(,模式,3),下,屏幕被划分成,25,行,每行可显示,80,个字符,所以,每屏最多可显示,2000(8025),个字符。为了便于标识屏幕上的每个显示位置,我们就用其所在行和列来表示之,并规定:屏幕的左上角坐标为,(0,0),,右下角坐标为,(24,79),。,在显示字符时,用一个字节存储该字符的,ASCII,码,用另一个字节存储的显示属性,即:显示颜
35、色。,由上面的叙述可知:在,8025,的文本显示模式下,满屏可显示,2000,个字符,也就需要,4000,个字节来存储一屏的显示信息。,第,8,章 输入输出和中断,2,、图形显示方式,图形显示是目前最常用的一种显示方式,也是,Windows,操作系统的默认显示方式。在该显示方式下,我们可以看到优美的图象、,VCD,、浏览丰富多彩的网页等。,图形显示的最小单位是象素,对每个象素可用不同的颜色来显示。所以,在显示缓冲区内记录的信息是屏幕各象素的显示颜色。,由于各种图形显示模式所能显示的颜色和象素是不同的,它决定了显示缓冲区的存储方式也是不同的。,第,8,章 输入输出和中断,例,8.2,用直接写屏方
36、式在屏幕第,5,行、第,10,列以黄色,(0EH),显示字符串“,Hello”,。,解:在文本显示方式下,每行显示,80,个字符,每个字符占,2,个字节,所以,显示一行需要,160,个字节。若在第,m,行、第,n,列位置显示字符,则该位置所对应存储单元的偏移量为:,m160+n2,。,例,8.3,用“霓虹灯”的显示方式显示字符串“,Hello”,,按,ESC,键时结束程序的运行。,解:我们用显示颜色的变化来模拟霓虹灯的显示方式,即用颜色,15(,亮白,),作为字符的主要显示颜色,再用颜色,12(,亮红,),从左到右逐个扫描。,例,8.4,编写一个输入密码的程序,该程序的具体要求如下:,1,、每
37、输入一个字符,显示字符”,#”,表示之;,2,、密码最多只有,10,个字符,多余的按键被丢弃;,3,、若输入的字符串为“,HELLO”,,则以蓝色显示”,Welcome”,,否则,以闪烁、亮红色在显示”,Invalid Password”,。,解:,第,8,章 输入输出和中断,例,8.5,在,256,色,320200,的图形显示模式下,从屏幕最左边向最右边,依次画竖线,(,从顶到底,),,线的颜色从,1,依次加,1,。要求用中断调用的方法来画线。,解:,例,8.6,在,256,色,320200,的图形显示模式下,从屏幕顶到屏幕底依次画横线,(,从最左边到最右边,),,线的颜色从,1,依次加,1,。要求用直接操作显示缓冲区的方法来画线。,解:,第,8,章 输入输出和中断,8.3.3,打印输出的中断功能,8.3.4,串行通信口的中断功能,8.3.5,鼠标的中断功能,8.3.6,目录和文件的中断功能,8.3.7,内存管理的中断功能,8.3.8,读取和设置中断向量,谢 谢,计算机科学系,200,3,年,03,月2,0,日,
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100