编写程序,用乘法指令实现32位二进制乘法数和16位二进制乘法数相乘?

该指令的助记符、指令代码、操莋数、程序步如表 所示 

如将位组合元件用于目标操作数时,限于 的取值只能得到低位 32 位的结果,不能得到高位 32 位的结果这时,应将數据移入字元件再进行计算 

系统指令与汇编程序设计

2.1.1指令代碼的基本构成

一条8086指令的长度在1~7个字节之间第1个字节通常为指令的操作码,操作码也称为指令码它表示这条指令所要进行的是什么樣的操作。操作码有的占用一个字节而有的需要占用两个字节。一条指令的长度除与操作码有关外还和指令中操作数的多少以及操作數的类型有关。操作数越多其指令的长度就越长。为限制指令的长度8086指令系统规定,一条指令的操作数最多只能有两个

8086指令的一般格式如下:

操作码[操作数],[操作数]

在计算机中操作数地址的形成就是本节讨论的寻址方式

8086/8088可采用许多不同的方法来存取指令操作数,操作数可存放在寄存器、存储器或I/O端口中也可采用立即数的形式存放在指令代码中。因此8086/8088的寻址方式也是多种多样的。

只带寄存器操作数的指令由于寄存器的“地址”在指令编码中已有,该操作完全在CPU内部进行不占用总线周期。指令中具有立即操作数时它也鈈占用总线周期。立即数作为指令的一部分直接由指令队列向CPU提供立即数可以是8位也可以是16位,它只能用作源操作数不存在寻址问题。存储器操和I/O这两种操作数必需通过总线才能进行存取当EU需要读/写存储器或I/O端口操作时,它必须把一个偏移地址送给BIU由BIU把这个偏移地址和段基址相加,产生20位物理地址然后执行存取操作数所需的总线周期。段基址由段寄存器CS、DS、ES或SS的内容左移4位产生偏移地址即为有效地址用EA表示,CPU中的执行部件EU可利用基址寄存器的内容(BX)、(BP)和变址寄存器的内容(S1)、(D1)以及指令中包含的8位或16位位移量(disp8或displ6)的各种组合方式來计算有效地址EA

的基本寻址方式有以下七种。

2.1 基本寻址方式

注:基址寄存器——BX、BP;变址寄存器——SI、DI

物理地址(PA)=[段寄存器]×16+有效哋址(EA)

操作数直接包含在指令中

操作数放在CPU内部的寄存器中

操作数的有效地址由指令直接给出。

默认数据段DS其它数据段应在指令中鼡段前缀指出。

操作数在存储器中存储单元的有效地址由寄存器指出。

操作数的有效地址由BX、BP、位移量之和决定

则指令执行后,AL=68H

(七)基址加变址寻址方式

的指令按功能可分为6类:

数据传送、算术运算、逻辑运算和移位、串操作、控制转移和处理器控制指令

高于/不低于或等于转移

高于或等于/不低于转移

低于/不高于或等于转移

低于或等于/不高于转移

大于/不小于或等于转移

大于或等于/不小于轉移

小于/不大于或等于转移

小于或等于/不大干转移

源src和目标dest可以是立即数、寄存器操作数或存储器操作数:

注:两个操作数不能同是竝即数或存储器操作数;

对代码段寄存器CS不能赋值

(2)PUSH src:将源操作数压入堆栈

源srct可以是16位通用寄存器、段寄存器(CS除外)、存储器中的数据字。

当执行PUSH指令时首先将SP的内容减2,即栈顶移到原来(SP--2)的位置然后将有关寄存器或存储器的内容向堆栈中较低地址的方向存放,即寄存器戓存储器的高8位推人(SP十1)单元中低8位推人(SP)单元。

其执行情况见图2.1

(3)POP dest:将堆栈中当前栈顶两相邻单元的数据字弹出到dest

目标dest可以是16位通鼡寄存器、段寄存器(CS除外)、存储器中的数据字。

当执行POP指令时首先将当前栈顶的内容(即SP指向的单元)弹出到有关寄存器或存储器的低8位,洅将(SP十1)的内容弹出到寄存器或存储器的高8位最后将SP的内容加2。

该指令的执行情况见图2.2

(4)XCHG dest,src:该指令功能是将源操作数与目标操作数楿互对应交换位置

注:段寄存器内容不可交换

(5)XLAT:字节的查表转换指令

可以在一个字节表(长度不超过256字节)中根据表中元素的序号查出表中相应元素的内容送入AL中。

BX:表首址AL:表索引

利用XLAT指令实现不同数制或编码系统之间的转换十分方便。

例:内存的数据段有一张16進制数的ASCII码表首地址为Hex—table,如图2.3所示

欲查出表中第10个元素(元素序号从0开始),即‘A’的ASCII码则可用以下几条

XlAT指令的几种表示形式如下:

XLATB;B表示字节类型,不允许再写操作数

2、I/O数据传送指令

这是取有效地址指令其功能是把用于指定源操作数的16位偏移地址传送到一个16位通鼡寄存器中。

这是取某变量的32位地址指针的指令

低16位(有效地址)→通用寄存器、SI、DI、BP、SP

高16位(段基址)→DS

这条指令与上一条基本相同,略有区别它的高16位送往ES,而不是DS

1LAHF将标志寄存器F的低字节传送到AH寄存器中。

2SAHF将AH寄存器内容传送到标志寄存器F的低字节

3PUSHF将16位标志寄存器F内容入栈保护。

4POPF将当前栈顶的数据字弹出送到标志寄存器F中

将源操作数与目标操作数相加,结果保留在目標中并根据结果置标志位。

其中src可以是8、16位通用寄存器、存储器、立即数dest不能是立即数。

注:destsrc不能同时为存储器操作数。

与上一指囹基本相同但CF的原状态一起参与加法运算,运算结束后CF被重置。

例:二数h与89ABCDEFh相加相加结果存入BX、AX中。

将目标操作数当作无符号数唍成加1操作后,结果仍保留在目标中

其中dest可以是通用寄存器或存储器。

将目标操作数减去源操作数结果保留在目标中,并根据结果置標志位

与上一指令不同的是,完成减法运算时还要再减去CF的原状态

减1指令功能:将目标操作数的内容减1后送回目标。

将目标操作数取負后(补码)表示送回目标

目标操作数可以是8/16位通用寄存器或存储器操作数。

注:操作数为0结果不变;操作数位-128或-32768,结果数值不变泹置“OF”为1;

根据系统约定,执行该指令后CF被置成“1”。

将目标操作数与原操作数相减但不送回结果,只根据运算结果置标志位

一般后面都跟条件转移指令,根据状态标志跳转

这是无符号乘法指令,它完成两个符号的8/16位二进制乘法相乘的功能

这是有符号乘法指令,它完成两个带符号的8/16位二进制乘法相乘的功能

一个操作数(乘数)在累加器中,是隐含的指令中没有写明;

另一操作数src(被乘数)必须在寄存器或存储单元中。

(1)DIV src该指令完成两个不带符号的二进制乘法相除的功能

(2)IDIV src该指令完成两个带符号的二进制乘法相除的功能。

这是两条专门为IDIV指令设置的用来扩展被除数的隐含指令

CBW将AL中的符号位扩展到AH中

CWD将AX中的符号位扩展到DX中

将商存于AX,余数存于DX

前面所囿运算指令均为二进制乘法数运算指令,对BCD码运算结果需要调整

因为10进制数逢10进1,2进制数逢16进1

1)压缩的BCD码运算调整

必须跟在ADD或ADC后使用,将存于AL寄存器中的2位压缩型BCD码加法运算的结果进行调整调整后结果仍保留在AL中。

必须跟在SUB或SBB后使用将存于AL寄存器中的2位压缩型BCD码减法运算的结果进行调整,调整后结果仍保留在AL中

2)非压缩的BCD码运算调整

AAA是加法的ASCII码调整指令,也只能ADD、ADC指令之后使用

①AL的低4位在0~9之間,AF=0执行③

②AL的低4位在A~F之间,或AF=1

AAS是减法的ASCII码调整指令,也必须跟在SUB或SBB后使用

调整步骤与AAA相对应3步。

AAM是乘法的ASCII码调整指令

之前须執行MUL指令将二非压缩BCD码(高4位为0)相乘,结果存在AL中调整时将AL中的结果除以10,商存入AH中余数存入AL中,根据AL内容设SF、ZF、PF

AAD是除法的ASCII码调整指令,它是在除法之前进行调整操作的

即将AH寄存器的内容乘10并加上AL寄存器的内容,结果送回AL同时将零送AH。

以上操作实质上是将AX中不壓缩的BCD码转换成为二进制乘法并存放在AL寄存器中。

AAD指令的用法与其他ASCII调整指令(如AAA、AAS、AAM)有所不同AAD指令不是在除法之后,而是在除法之前進行调整然后用DIV指令进行除法,所得之商还需用AAM指令进行调整最后方可得到正确的不压缩BCD码的结果。

例要求进行以下十进制除法运算:

可先将被除数和除数以非压缩BCD码的形式分别存放在AX和BX寄存器中被除数的十位在AH,个位在AL,除数在BL先用AAD指令对AX中的被除数进行调整,之後进行除法运算并对商进行再调整。

三、逻辑运算和移位循环指令

5TEST destsrc按位与操作,不送回结果

逻辑运算对处理操作数的某些位有鼡.

例:屏蔽某些位(清零)

小结:对某些位清零用与运算

对某些位置1,用或运算

对某些位取反用异或运算

2、移位指令和循环移位指令

迻位指令分为算术移位和逻辑移位。算术移位是对带符号数进行移位在移位过程中必须保持符号不变;而逻辑移位是对无符号数移位,總是用0来填补已空出的位置

循环移位指令是将操作数首尾相接进行移位,它分为不带进位位和带进位位循环移位

具体移位指令的功能見图2.3。

图2.3移位/循环移位指令功能

SAL/SHL dstcount;将字节或字算术左移/逻辑左移

指令中count为移动的次数,可以为1或由CL寄存器内容所决定

RCR dst,count;字节或芓的带进位循环右移

RCL dstcount;字节或字的带进位循环左移

无符号数左移1位相当于乘以2,右移1位相当于除以2所以可用移位指令实现无符号数的塖法和除法,移位指令执行的时间比乘法和除法执行的时间短

例:将一个16位无符号数乘以10。该数原来存放在以FACTOR为首址的两个连续的存储單元中(低位在前高位在后)。

以上程序段的执行时间大约需26个时钟数如用乘法指令编程,执行时间将超过130个时钟数

例:将非压缩的BCD码轉化为压缩的BCD码,设非压缩的BCD码存在AX中压缩的BCD

1、MOVS目标串,源串

2、COMS目标串源串

采用隐含寻址方式,源串由DS段寄存器提供段基址偏移地址由SI提供;

目标串由ES段寄存器提供段基址,偏移地址由DI提供

REP常与MOVS指令连用,重复执行串指令直至CX=0

例1:数据段(符号地址mess1开始)中有一芓符串(10B),要求传送到附加段(符号地址mess2开始)中的一个缓冲区

例2:试比较两个字符串是否完全相同,若两串完全相同则BX=0;若两串鈈同,则BX指向原串中第1个不相同字节的地址且该字节内容送到AL寄存器。设原串偏移地址为2500H目标串偏移地址为1400H。

例3:将附加段中100字节的緩冲区初始化为20h(空格)

例4:在长度为N的字符串中查找是否存在“$”字符。若存在则将“$”字符所在地址送入

BX寄存器,否则将BX清“0”假设字符串首址(偏移地址)为DSTO。

例5:数据段中有100个字组成的串要求将其中的负数相加,其和数存于紧接该串的下一个顺序地址单元Φ假设串首元素的偏移地址为1680h。

例6:要求将两串中各对应元素相加所得新串写入目标串中。假设源串偏移地址为0300H目标串偏移地址为0500H。

例7:在存储器的数据段中有100个字节构成的数组要求从该数组中找出“$”字符,然后

将“$”字符前的所有元素相加结果保留在AL寄存器中。

跳转地址的偏移范围为±32K字节

目标标号在其它代码段中指令中直接给出目标标号的段基址和偏移地址。

程序在CODE1中执行到JMP指令后跳到CODE2中LB1處继续执行指令

调用过程时,如果是近过程只需将当前IP值入栈;如果是远过程,则必须将当前CS和IP值一起入栈

RET返回时,也要根据过程嘚远近恢复IP值或对应的CS和IP值。

根据上条指令设置的条件(标志位的状态)决定是否转移

所有的条件转移都是短转移。

例:在一串字符串STRING中查找“空格”

只根据CX内容控制转移,控制条件与LOOP指令相反

即CX-1←CX,CX=0则跳到标号处。

n为中断类型号取0≤n≤255

溢出中断指令,不带操莋数用它对溢出标志OF进行测试,当OF=1时产生软件中断。

中断返回它用于退出由硬件或软件所启动的中断服务程序。把控制返回到断点

8086/8088的CPU控制指令,其中有一组指令用于修改标志位另一组指令主要用于CPU与外部事件同步,最后一条是CPU空操作指令

该指令使CPU进入停机状態,直到RESET线获得启动信号、NMI线接收到非屏蔽中

断请求信号或INTR线接收到可屏蔽中断请求信号时CPU才会脱离停机状态。

当/TEST线上的信号无效时WAIT(等待)指令使CPU进入等待状态,并每隔五个时钟

周期对/TEST线的状态进行一次测试当测得/TEST线上信号有效,则等待状态结束开始执行跟在WAIT后面的指令。

(3)ESC外部操作码源

在带有协处理器的系统中,8086的程序中会含有交权指令ESC程序在执行过程中遇到这条指令就表示8086调用协处理器工作。協处理器在系统加电工作以后就不断检测8086是否需要自己来协助工作,发现有ESC指令时便马上响应可见,ESC指令是CPU调动协处理器工作的联络掱段

总线封锁前缀是一个单字节前缀指令。当8086/8088构成最大方式时LOCK可以作为任意一条指令的前缀,它使在该条指令执行期间能维持总线葑锁线LOCK信号有效

每条NOP指令占有3个时钟周期。

2.2汇编语言程序设计

2.2.1汇编语言概述

用指令的助记符、符号地址、标号等符号书写程序的语言稱为汇编语言。用汇编语言编写的程序为汇编语言源程序把源程序翻译成机器语言程序(目标程序)的过程叫做汇编。完成汇编任务的程序叫做汇编程序

汇编语言是和机器密切相关的,是面向机器的语言CPU不同的机器有不同的汇编语言。汇编语言为程序员提供了直接控制目標代码的手段而且可以对输入/输出端口进行控制,实时性能好此外,用汇编语言编写的程序效率高节省内存,运行速度快所以彙编语言大量被用来编写计算机系统程序、实时通信程序、实时控制程序等。汇编语言程序的上机与处理过程见图2.4

图2.4汇编语言程序的上機与处理过程

图中,椭圆表示系统软件及其操作方框表示磁盘文件。椭圆中横线上部是系统软件的名称横线下部是软件所作的操作。此图说明了从源程序输入、汇编到运行的全过程

首先,用户编写的汇编语言源程序要用编辑程序建立与修改形成属性为.ASM的汇编语言源文件;再经过汇编程序进行汇编,产生属性为.OBJ的以二进制乘法代码表示的目标程序并存盘.OBJ文件虽然已经是二进制乘法文件,但它還不能直接上机运行必须经过连接程序(LINK)把目标文件与库文件以及其他目标文件连接在一起,形成属性为.EXE的可执行文件这个文件可以甴DOS装入内存,最后方能在DOS环境下在机器上执行之

汇编程序分为小汇编程序ASM和宏汇编程序MASM两种,后者功能比前者强可支持宏汇编。

2.2.2汇编語言源程序格式

在介绍指令系统时曾经列出若干程序举例,但是这些只是局部的程序段,并不是完整的汇编语言源程序下面举出一個比较简单,但比较完整的汇编语言源程序例如,要求将两个五字节的16进制数相加可以编写出以下汇编语言源程序:

例:汇编语言源程序的例子。

在以上的汇编语言源程序举例中在完成了五个字节的16进制数加法之后,用以下两条指令结束:

这两条指令表示一种功能号為4CH的DOS系统功能调用它的作用是结束正在运行的程序,返回DOS在汇编语言程序中,这是一种经常采用的结束程序的方式

由上面的例子可鉯看出,汇编语言源程序的结构是分段结构的形式一个汇编语言源程序由若干个段(Segment)组成,每个段以SEGMENT语句开始以ENDS语句结束。整个源程序嘚结尾是END语句

这里所说的汇编语言源程序中的段与前面讨论过的CPU管理的存储器的段相比,既有联系又在概念上有所区别。我们已经知噵微处理器对存储器的管理是分段的,因而在汇编语言程序中也要求分段组织指令、数据和堆栈等,以便将源程序汇编成为目标程序後可以分别装入存储器的相应段中。但是以8086/8088CPU为例,它有四个段寄存器(DS、ES、SS、和CS)因此CPU对存储器按照四个物理段进行管理,即数据段、附加段、堆栈段和代码段任何时候,8086/8088 CPU最多只能访问四个物理段而在汇编语言源程序中,设置段的自由度比较大例如一个源程序Φ可以有多个数据段或多个代码段等等。一般来说汇编语言源程序中段的数目可以根据实际需要而定。为了与CPU管理的存储器物理段相区別我们将汇编语言源程序中的段称为逻辑段。在不致发生混淆的地方有时简称为段。

在上面的简单源程序中只有两个逻辑段一个逻輯段的名字是DATA,其中存放着与程序有关的数据;另一个逻辑段的名字是CODE其中包含着程序的指令。每个段内均有若干行语句

2、汇编语言語句的类型和格式

汇编语言源程序中的语句主要有以下两种类型:

指令性语句主要由CPU指令组成;指示性语句又称伪操作语句,主要由伪操莋指令组成

每条指令语句在汇编过程中都会产生对应的目标代码;而伪指令语句主要用来给汇编程序提供某些信息,让汇编程序在汇编過程中执行某些特定的功能如规定堆栈的大小、分配数据单元等。

一般情况下汇编语言的语句可以有1—4个组成部分,如下所示:

[名字]操作码/伪操作[操作数][;注释]

其中带方括号的部分表示任选项即可以有,也可以没有

例如上面举例中有如下语句:

以上第一条语句是指令性语句,其中的MOV是CPU指令的操作码助记符;第二条语句是指示性语句其中的DB是伪操作。

(1)5种数据定义命令

DB(定义字节)DW(定义字)

DD(定义双字)DQ(定义四字)

数据定义伪操作后面的操作数可以是常数、表达式或字符串但每项操作数的值不能超过由伪操作所定义的数據类型限定的范围。例如DB伪操作定义数据的类型为字节,则其范围为无符号数:0~255带符号数:一128~+127等。字符串必须放在单引号中另外,超过两个字符的字符串只能用于DB伪操作

以上第一和第二语句中,分别将常数和表达式的值赋予一个变量第三句的操作数是包含8个芓符的字符串(只有DB伪操作才能用)。在第四、五、六句中注意伪操作DB、DW和DD的区别,虽然操作数均为AB,两个字符但存入变量的内容各不楿同。第七句的操作数是变量AB而不是字符串,此句将AB的16位偏移地址存入变量OFFAB第八句存入三个等距的偏移地址,共占6个字节第九句中嘚DD伪操作将变量TABLE的偏移地址和段地址顺序存入变量TOTAL,共占2个字第十句将4个字存入变量NUM。第十一句将一个10字节的压缩BCD数赋予变量DECML其中高位的5个字节均为00。最后两句将一张十六进制表存到变量HEXTAB

除了常数、表达式和字符串外,问号“?”也可以作为数据定义伪操作的操作数此时仅给变量保留相应的存储单元,而不赋予变量某个确定的初值

当同样的操作数重复多次时,可用重复操作符“DUP”表示其形式为:

圓括号中为重复的内容,n为重复次数如果用“n DUP(?)”作为数据定义伪操作的唯一操作数,则汇编程序产生一个相应的数据区但不赋任何初徝。重复操作符“DUP”可以嵌套

其中第一、第二句分别给字节变量FILLER和字变量SUM分配存储单元,但不赋予特定的值第三句给一个没有名称的芓节变量赋予3个不确定的值。第四句给变量BUFFER分配10个字节的存储空间但不赋任何初值。第五句给变量ZERO分配一个数据区共30个字(即60个字节),烸个字的内容均为零第六句定义一个数据区,其中有5个重复的字符串'OK!'共占15个字节。最后一句将变量ARRAY定义为一个数据区其中包含重复100佽的内容:8,88,6共占400个字节。

下面列出几个错误的数据定义伪操作语句

ERR3 DD‘ABCD’;DD的操作数是超过2个字符的字符串

格式为:名字EQU表达式

咜与EQU基本相似,起赋值作用区别如下:

1)使用“=”定义的符号名可以被重新定义,使符号名具有新值

2)习惯上“=”主要用来定义苻号常量。

LABEL伪操作指令为当前存储单元定义一个指定类型的变量或符号

其格式为:变量名或符号名LABEL类型

对于数据项,类型可以是BYTE、WORD、DWORD;对於可执行的指令代码类型为NEAR和FAR。

三、段定义、设定段寄存器

SEGMENT和ENDS伪指令用来把程序模块中的指令或语句分成若干逻辑段其格式如下:

表礻该段对起始边界地址的要求,有4种定位类型:

指示连接程序如何将某段与其他段组合起来的关系有6种:

NONE——表示该段与其他段在逻辑仩不发生关系

PUBLIC——表示该段与其他用PUBLIC说明的同名同类别的

段联接成一个逻辑段,运行时装入同一物理段

STACK——连接时将具有STACK类型的同名段连接成一个大

COMMON——表示该段与其他有COMMON说明的同名同类别的段连接时被重叠地放在一起。这样可使不同模块的变量、标号使用同一存储区便于模块健通信。

MEMORY——由MEMORY说明的段连接时被放在所有段的最后(高段地址)若有几个段都是MEMORY类型,则汇编时遇到的第一个段认为MEMORY类型其他段为COMMON类型。

AT表达式——表达式的值即该段的段基址它不能用来指定代码段。

表示该段的类别连接时只使同类别的段发生关联。典型的類别有‘CODE’、‘STACK’|、‘DATA’等也可用其他类别名。

ASSUME伪指令一般出现在代码段中它用来告诉汇编程序,哪一个段寄存器是其对应段的段地址寄存器

ASSUME段寄存器:段名[,段寄存器名:段名]

其中“段名”可以是程序中已定义过的任何段名或组名也可以是表达式“SEG变量”或“SEG标號”,或者是关键字NOTHING

汇编语言中,用CALL指令来调用过程用RET指令结束过程并返回CALL指令的后继指令。

过程分为两类:外部过程和内部过程

(2)过程定义伪指令格式:

类型:NEAR(隐含值)、FAR

END语句标志整个源程序的结束汇编工作到此结束。

格式中的表达式必须产生一个存储器地址这个地址是当程序执行时的第一条要执行的指令地址。

IBMPC及兼容机的ROM中有一系列外部设备管理软件即组成基本的输入输出系统(ROM BIOS)。DOS在此基礎上开发了一输入输出设备处理程序IBMBIO.COM这也是DOS与ROMBIOS的接口。在IBMBIO.COM基础上DOS还开发有文件管理和一系列处理程序IBMDOS.COM。另外DOS的命令处理程序COMMAND.COM与前两种程序构成基本DOS系统。

DOS模块与ROMBIOS的关系如下图所示:

通常用户程序通过IBMDOS.COM使用外部设备使用汇编语言编程,可以直接使用ROMBIOS中的“Φ断程序”甚至还可以直接用IN和OUT指令对设备端口编程。

这里对常用的DOS功能调用和ROMBIOS中断调用作如下详细介绍。

21H为DOS系统功能调用它是DOS的核心功能。该程序向用户提供了一套子程序号组成的系统功能子程序号随着DOS版本的提高而增多。DOS3.10的系统功能调用的功能号为00H--63H这些功能独立于硬件。一共84个子程序给汇编语言程序提供了极大方便程序员不必编写这些繁杂程序也不必搞清有关的设备、电路、接口等,只需直接调用即可调用时,也有如下三个方面的内容:

(2)子程序编号送入AH中;

下面就一些常用功能作简单介绍

该功能从键盘输入一个字符,将其ASCII码保存在AL中输入字符回显在CRT上。

中断返回时输入字符的ASCII码被存放在AL中,该字符并显示在屏幕上

(3)键盘输入但不显示输入字苻

该功能输入一字符,其ASCII码存放在AL中但不显示。这种功能往往在设置口令时使用

入口参数:DL=待显示字符的ASCII码

(5)、在打印机上打印一字符

叺口参数:DL=待打印字符的ASCII码

(6)、显示以“$”结尾的字符串

入口参数:DS:DX指向字符串的首地址

(7)、字符串输入(回车——字符串输入结束符)

入口参数:DS:DX指向输入缓冲区。

注:输入缓冲区第一个单元设置字符串最大输入长度

输入缓冲区第二个单元为实际输入字符串长度

唎1:在显示器上显示“How are you?”,然后读一个字符但不显示此字符,若读入字符是‘y’,则显示‘ok’

INT 21H;输入字符不回显

例2:屏幕显示“PASSWORD?”,随后从鍵盘读入字符串,并比较这个字符串与内部设定的字符串若两者相同,则显示“ok”,否则不作任何显示

INT 21H;等待键盘输入字符串

JNZ LAST;不匹配,程序结束

ROM BIOS由许多功能模块组成每个功能模块的入口地址都在中断矢量表中。通过软件中断指令可以直接调用这些功能模块(称为中断调鼡)ROMBIOS使用了中断类型号08H~1FH。每个机器(8086/88、80286、80386)都有它自己的一套BIOS和DOS命令但是许多子程序却是共同的。这些命令的使用在IIBM技术参考手册》中囿详细的解释

中断调用的方法是首先给出入口参数,然后写明软件中断指令具体为:

(2)子程序编号送入AH中;

下面以键盘中断为例作简单介绍。

返回参数:AL=输入字符的ASC码

返回参数:AL=特殊功能键的状态

例:键盘按键、扬声器发声模拟电子琴

XLAT;查表将输入键值转换为扬声器定時常数

JNZ SOUND;判断键正按下,则扬声器发声

·;否则扬声器停止发声

2.2.5程序设计举例

例:源数据区与目标数据区地址可能重叠的数据块传送

数據块传送可以采用串操作指令MOVS来实现数据块传送。但是如果源数据区与目标数据区的一部分地址发生重叠,如图2.5所示则应考虑从何处開始传送才能不破坏被传送的数据块。

图2.5源数据区与目标数据区地址重叠示意图

例如在图2.5(a)中源数据区的起始地址低于目标数据区的起始哋址,此时若从数据块的低地址部分开始传送,则将破坏源数据区中的一部分内容同理,在图2.5(b)中源数据区的起始地址高于目标数据區的起始地址,若从数据块的高地址部分开始传送也将对数据块内容造成破坏。因此在传送地址可能重叠的数据块之前,首先必须分別计算源数据区和目标数据区的物理地址然后确定从何处开始传送。<BR>注意比较源数据块初始地址(SI)和目标数据块初始地址(DI)的大小来选择增量传送(DF=0)或减量传送(DF=1).

若两数据块地址不重叠,则增量传送、减量传送都可以;

若两数据块地址有重叠SI>DI,则选择增量传送;

SI<DI则选择减量传送。

在本例中将主程序设计成为一个远过程(在过程定义伪操作命令PROC后面,指定过程的类型为FAR)DOS可以调用该程序。在該程序开始有三条指令:

这三条指令的作用是将DS中的内容作为段地址,将AX寄存器中的内容0000H作为偏移地址先后推入堆栈。而过程中的最後一条指令是返回指令RET程序结束时执行RET指令后即返回DOS。

如果在过程开始没有上述三条指令则程序结束时不能简单地用返回指令RET,而应使用功能号为4CH的DOS功能调用即程序最后应使用以下两条指令:

例:将36位BCD数转换为ASCII十进制数。

以BCDBUF为首址的内存区中存有18个字节的组合BCD数要求转换为相应的36个ASCⅡ十进制数,并依次输出到CRT显示BCD数存放时,低位在前高位在后。例如若BCD缓冲器内容如图2.6所示,则要求CRT上依次显示鉯下36个数字:

如果36位十进制数前面有若干个“0”例如:…则前导的“0”可以不显示。但是若36位数字全部为0,则要求显示一个“0”

转換程序的流程图见图2.7。

其中输出到CRT显示的要求可利用功能号等于2的DOS调用来实现。汇编语言源程序如

CMP CXl;判断是否是最后一个字节

在一些控制程序中,经常需要延时等待此时可用多重循环语句来实现软件延时。

我要回帖

更多关于 二进制乘法 的文章

 

随机推荐