版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第3章汇编语言程序设计初步3.1系统功能调用3.2汇编语言源程序的设计的基本步骤3.3分支结构的汇编语言源程序的编写3.4循环结构的汇编语言源程序的编写开始第3章汇编语言程序设计初步3.1系统功能调用开3.1
系统功能调用3.1.1系统功能调用概述3.1.2基本I/O调用返回本章首页3.1系统功能调用3.1.1系统功能调用概述返回本章3.1.1系统功能调用概述
我们在编制汇编源程序时,常常要与外部设备发生关系,如希望能从键盘输入字符或在显示器上显示出程序运行的结果,但由于计算机机种的不同、外部设备型号的差异,控制它们工作的程序也会有差异。如果每次都需要根据自己的工作环境来设计“控制这些外设工作的程序”,则必须要先弄清楚与之有关的设备、电路、接口等各方面的情况,是一件既复杂,效率又低的事情,并且没有通用性。如果把这些控制过程预先编写成一个一个子3.1.1系统功能调用概述我们在编制汇编程序,作为操作系统的一部分事先放在系统盘上,用户在需要时只要按规定的格式设置好参数,直接调用这些子程序即可。美国MICROSOFT公司为我们提供的磁盘操作系统(DOS)就具有这种功能,称为“利用操作系统的标准功能调用(简称系统功能调用)”,编号从0~62H(3.0版),主要分为设备管理(如键盘、显示器、打印机、磁盘等的管理)、文件管理、目录管理及其他功能调用4大类。程序,作为操作系统的一部分事先放在系统盘上,用户在需要时只要●系统功能调用的基本方法采用一条软中断指令INTn。所谓中断,是指当计算机正在执行正常的程序时,计算机系统中的某个部分突然出现某些异常情况或特殊请求,CPU这时就中止(暂停)它正在执行的程序,而转去执行申请中断的那个设备或事件的中断服务程序,执行完这个服务程序后,再自动返回到程序断点执行原来中断了的正常程序。这个过程或这种功能就叫做中断。软中断是以指令方式产生的中断,n是中断类型号,不同的n将转入不同的中断处理程序。系统功能调用是21号软中断。●系统功能调用的基本方法采用一条软中断指令I常用的系统功能调用表:表3-1最常用的系统功能调用表常用的系统功能调用表:表3-1最常用的系统功能调用表●系统功能调用的步骤:1)将调用参数装入指定的寄存器。2)如需要功能调用号(即欲调用的子程序编号),把它装入寄存器AH。3)如需要子功能调用号,把它装入AL。4)按中断号调用DOS(发出中断指令:INT21H)。5)检查返回参数是否正确。●系统功能调用的步骤:1)将调用参数装入指定的寄存器。
3.1.2基本I/O调用1.01H号调用
功能:从标准输入设备上(通常为键盘)读取字符,并在标准输出设备上(通常为显示器)回显。
格式:MOVAH01H INT21H
说明:输入字符的ASCII码送入AL中,如果读到的字符是Ctrl+C或Ctrl+Break,则结束程序。2.02H号调用
功能:通过标准输出设备(多为显示器)输出字符。 3.1.2基本I/O调用1.01H号调用
格式:MOVDL,
X;(X为要输出显示的ASCII字符代码)
MOVAH,02H
INT
21H
说明:DL寄存器中的内容等于要输出字符的ASCII码,在显示输出时检查到的字符是Ctrl+C或Ctrl+Break键的,则结束程序。3.09H号调用
功能:在标准输出上(通常为显示器)显示一个字符串。字符串要以字符“$”为结束标志。
格式:MOVAH09H
INT
21H说明:要输出显示的字符串的首地址送到DS、DX两个寄存器中,其中段地址送DS寄存器,格式:MOVDL,X;(X为要输出显示偏移地址送DX寄存器。4.0AH号调用功能:从标准输入设备上(通常为键盘)读一个字符串,存入内存,直到按回车键为止。格式:MOVAH,0AH INT21H说明:此项操作,要求事先定义一个输入缓冲区,它的缓冲区首地址送到DS、DX两个寄存器中,其中段地址送DS寄存器,偏移地址送DX寄存器。偏移地址送DX寄存器。【例3-1】在显示器上显示字符串WelcometoTianHecollege!DATASSEGMENT;/数据段定义开始
STRINGDB'WelcometoTianHecollege!',0AH,0DH,'$';/定义字符串,0AH,0DH表示显示字符串后,光标可自动
回车换行,字符串必须以$结束。
DATASENDS;/数据段定义结束CODESSEGMENT
;/代码段定义开始ASSUMECS:CODES,DS:DATAS,SS:STACKS;
/说明段和段寄存器之间的关系START:
MOVAX,DATAS;/将数据段的段地址送寄存器AX
MOVDS,AX;/将AX内容送DS寄存器,即初始化DS
LEADX,STRING;/将STRING的偏移地址送DX寄存器
【例3-1】在显示器上显示字符串WelcometoTi
MOVAH,9
;/字符串显示子功能,9号系统功能调用
INT21H;/系统调用
MOVAH,4CH;/返回DOS
INT21H
;/系统调用CODESENDS;/代码段定义结束ENDSTART【例3-2】从键盘输入字符串,把它放到缓冲区中存储起来。DATASEGMENT
MAXLENDB100
;/定义缓冲区的最大容量
ACLENDB?
;/定义实际读入的字符数
STRINGDB100DUP(?);/定义接收字符串空间DATAENDSMOVAH,9;/字符串显示子功能,9号系CODESEGMENT
MOVAX,DATA
MOVDS,AX
;/数据段初始化
LEADX,MAXLEN
;/送
MAXLEN的偏移地址到寄存器DX
MOVAH,10;/10号系统功能调用
INT21H;/系统调用CODEENDS运行程序时,若从键盘输入“Thankyou!”(共计10个字符),则输入缓冲区MAXLEN各单元的内容如图3-1所示。图3-1存储空间分配示意CODESEGMENT图3-1存储空间分配示意
3.2
汇编语言源程序的设计的基本步骤3.2.1源程序的基本框架3.2.2汇编语言源程序设计的基本步骤3.2.3顺序结构的汇编语言源程序的编写返回本章首页 3.2汇编语言源程序的设计的基本步骤3.2.1源程序3.2.1源程序的基本框架
一个汇编语言源程序由两大部分组成的。其中主要部分就是指令,位于代码段内,代码段可以有好几个。其他部分是为指令服务的,包括数据的准备,存储区域的划分和地址的标注。其他部分由数据段、堆栈段和扩展段组成。也各可以有好几个。段之间的顺序可以随意安排。但通常是其他部分(数据段、堆栈段和扩展段等)在前,代码段在后。虽然可以定义多个段,但由于段首址存放在CPU的寄存器中,所以可以同时使用6个段:代码段(CS)、数据段(DS)、堆栈段(SS)和3个扩展段(ES、FS和GS)。扩展段其实也是数据段,只是段地址在寄存器ES、FS和GS中。程序通过修改段寄存器的值实现段的切换。3.2.1源程序的基本框架一个汇编语言源程一个程序至少包含一个代码段和END指令。其他段的设置由程序的具体功能需要而定。程序较小时,可以不设置堆栈段。操作系统在装载不含堆栈段的程序时,会指定一个段作为堆栈段使用。这样,程序连接时,LINK会产生一条警告信息: WARNING:NOSTACKSEGMENT
但不会影响程序的运行,可以忽略它。
程序中的段名可以是唯一的,也可以与其它段同名。在同一模块中,如果有两个段同名,则后者被认为是前段的后续,这样,它们就属同一段。当同一模块出现两个同名段时,则后者的可选项属性要么与前者相同,要么不写其属性而选用前者的段属性。一个程序至少包含一个代码段和END指令。其他段的设置由程序的【例3-4】段寄存器与段的对应方法1:用一个段寄存器对应两个数据段DATA1SEGMENT;/定义第一个数据段
b1DB10h
;/定义变量DATA1,字节变量DATA1ENDS
;/第一个数据段结束DATA2SEGMENT
;/定义第二个数据段
b1DB23h
;/定义变量DATA2,字节变量DATA2ENDS
;/第二个数据段结束CODE1SEGMENT
;/定义第一个代码段ASSUMECS:CODE1,DS:DATA1;/指定段寄存器START:MOVAX,DATA1;/指令开始,
MOVDS,AX;/把数据段DATA1的段首址赋给段寄存器DS【例3-4】段寄存器与段的对应方法1:用一个段寄存器对应两个………………
MOVBL,b1;/引用DS来访问DATA1中的变量b1………………ASSUMEDS:DATA2;/说明DS与DATA2建立联系MOVAX,DATA2;MOVDS,AX;/把数据段DATA2的段值赋给段寄存器DS………………
/实现段的切换MOVAL,b2;/引用DS来访问DATA2中的变量b2………………CODE1ENDS;/代码段CODE1结束ENDSTART;/程序结束
在方法1中,因为只使用一个段寄存器DS来对应两个数据段,所以,需要切换DS的对应关系。但我们也可以用段寄存器DS和ES来分别对应段DATA1和DATA2,这样,方法1就可变成方法2。………………方法2:用两个段寄存器对应两个数据段DATA1SEGMENT;/定义第一个数据段
b1DB10h;/定义变量DATA1,字节变量DATA1ENDS;/第一个数据段结束DATA2SEGMENT;/定义第二个数据段
b2DB23h;/定义变量DATA2,字节变量DATA2ENDS;/第二个数据段结束CODE1SEGMENT;/定义第一个代码段ASSUMECS:CODE1,DS:DATA1,ES:DATA2;/指定段寄存器START:MOVAX,DATA1;/指令开始,
MOVDS,AX;/把数据段DATA1的段首址赋给段寄存器DS
MOVAX,DATA2
MOVES,AX;/把数据段DATA2的段首址赋给段寄存器ES………………
方法2:用两个段寄存器对应两个数据段
MOVBL,b1;/引用DS来访问DATA1中的变量b1………………
MOVAL,b2;/引用ES来访问DATA2中的变量b2………………
CODE1ENDS;/代码段CODE1结束ENDSTART;/程序结束
我们还可以用“段组”来简化段寄存器的使用,把段DATA1和DATA2组成一个数据段。所以,把方法2再改写成方法3的形式。方法3:用一个段组组成两个数据段GSEGGROUPDATA1,DATA2;/定义段组DATA1SEGMENT;/定义第一个数据段MOVBL,b1
b1DB10h;/定义变量DATA1,字节变量DATA1ENDS;/第一个数据段结束DATA2SEGMENT;/定义第二个数据段
b2DB23h;/定义变量DATA2,字节变量DATA2ENDS;/第二个数据段结束CODE1SEGMENT;/定义第一个代码段
ASSUMECS:CODE1,DS:GSEGSTART:MOVAX,GSEG;/指令开始,
MOVDS,AX;/把段组GSEG的段值赋给段寄存器DS………………
MOVBL,b1;/引用DS来访问DATA1中的变量b1………………
MOVAL,b2;/引用DS来访问DATA2中的变量b2………………b1DB10h………………
CODE1ENDS;/代码段CODE1结束ENDSTART;/程序结束
定义段组后,段组内各段所定义的标号和变量,除了与定义它们的段起始点相关外,还与段组的起始点相关。规定如下:
如果在ASSUME伪指令中说明段组与段寄存器相对应,那么,有关标号或变量的偏移量就相对于段组起点计算;
如果在ASSUME伪指令中说明段组内的某段与段寄存器相对应,那么,有关标号或变量的偏移量就相对于该段的起点。
所以,在使用段组后,程序员要谨慎使用ASSUME伪指令,并保证段寄存器的值与段组或段相一致。………………定义段组后,段组内各段所定义
3.2.2汇编语言源程序设计的基本步骤1.汇编语言源程序的主要基本结构:
顺序结构
分支结构
循环结构2.好程序的要求一个好的程序,首先应该能正常运行,实现预定的功能。还应该满足:结构简明,明白易懂,调试方便,修改容易。执行速度快(程序执行时间短,程序语句行数尽量少)。占用内存空间少。 3.2.2汇编语言源程序设计的基本步骤1.汇编语言源程3.基本步骤分析问题,从中抽象出恰当的数学模型。确定解决问题的合理算法。画出程序流程图,根据算法,细化并找出解决问题的思路和具体方法。确定汇编语言程序的基本框架:各个存储段的定义,存储空间的分配,寄存器的配置,指针和计数器的选择。根据程序流程图确定程序的基本结构,并编写程序。3.基本步骤3.2.3顺序结构的汇编语言源程序的编写
顺序结构是最简单的程序结构,没有分支,没有循环,程序的执行顺序就是指令的编写顺序,所以,又称直线程序。因此,安排指令的先后次序就显得至关重要。另外,在编程序时,还要妥善保存已得到的处理结果,为后面的进一步处理直接提供前面的处理结果,从而避免不必要的重复操作。3.2.3顺序结构的汇编语言源程序的编写顺序结构【例3-5】两个64位无符号数相加●分析问题:在8086/8088CPU中,只有8位或16位运算指令,没有32位和64位以上的运算指令。●确定算法:要进行64位的加法运算,可以确定算法:利用16位加法指令分别相加4次来实现。●画程序流程图:本问题简单,无需画程序流程图。●确定汇编语言程序的基本框架:可见,汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义3个变量:两个加数N1、N2,还有一个和数SUM,都是DW类型。和数SUM尚属未知,故应定义一个5个字长(比64位字长富余一点)的缓冲区。因为要加4次,需要一个计数器或指针,可选寄存器BX充当。●编写程序,可以想得到,需要MOV、ADD、ADC和INC等指令。具体程序如下:【例3-5】两个64位无符号数相加●分析问题:在8086/8DATASEGMENT;/定义数据段 N1DW1234H,5678H,9ABCH,0DEF0H;/定义字变量N1
N2DW1971H,0313H,1968H,1123H;/定义字变量N2
SUMDW5DUP(?);/定义缓冲区SUMDATA1END;/数据段结束CODESEGMENT;/定义第一个代码段
ASSUMECS:CODE,DS:DATA;/指定段寄存器MAINPROCNEARSTART:MOVAX,DATA;/指令开始,
MOVDS,AX;/把数据段的段首址赋给段寄存器DS
LEABX,N1;/将N1的偏移地址送BX
MOVAX,[BX];/引用DS来访问DATA中的变量N1的最低位DATASEGMENT;/定义数据段
ADDAX,[BX+8];/最低位字相加,因两个数偏移地址相差8个字节
MOV[BX+16],AX;/存最低位和。[BX+16]指示SUM的偏移地址
此句也可以写为:MOV[SUM],AX
INCBX
INCBX;/指针指向下一个字
MOVAX,[BX];/引用DS来访问DATA中的变量N1的次低位 ADCAX,[BX+8];/次低位字相加,因两个数偏移地址相差8个字节
MOV[BX+16],AX;/存次低位和。[BX+16]指示SUM+1的偏移
地址,此句也可以写为:MOV[SUM+1],AX
INCBX
INCBX;/指针指向下一个字
MOVAX,[BX];/引用DS来访问DATA中的变量N1的次高位
ADCAX,[BX+8];/次高位字相加,因两个数偏移地址相差8个字节ADDAX,[BX+8]
MOV[BX+16],AX;/存次高位和。[BX+16]指示SUM+2的偏移
地址,此句也可以写为:MOV[SUM+2],AX
INCBX INCBX
;/指针指向下一个字
MOVAX,[BX]
;/引用DS来访问DATA中的变量N1的最高位
ADCAX,[BX+8]
;/最高位字相加,因两个数偏移地址相差8个字节
MOV[BX+16],AX;/存最高位和。[BX+16]指示SUM+3的偏移
地址,此句也可以写为:MOV[SUM+3],AX
MOVAX,0
;/对AX清零
ADCAX,0
;/计算进位
MOV[BX+18],AX;/存进位位
MOVAH,4CH
;/此句也可写成:MOVAX,4C00H
INT21H
MAINENDP CODEENDS
;/代码段CODE1结束
ENDSTART
;/程序结束
MOV[BX+16],AX;/存次高位和。[【例3-6】两个32位无符号数乘法程序●分析问题:在8086/8088CPU中,只有8位或16位运算指令,没有32位以上的乘法运算指令。●确定算法:要进行32位的乘法运算,可以确定算法:利用16位乘法指令做4次乘法,然后把部分积相加来实现。每次的积的低位送AX,高位送DX。如图3-2所示。●画程序流程图:程序流程图如图3-3所示。●确定汇编语言程序的基本框架:可见,汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义3个变量:两个乘数,还有一个积数,都是DW类型。积数尚属未知,故应定义一个4个字长(积的字长应该是乘数字长的两倍)的缓冲区。因为要乘4次,需要一个计数器或指针,可选寄存器BX充当。另外,本程序为了教学的需要,不采用 MOVAH,4CH INT21H【例3-6】两个32位无符号数乘法程序●分析问题:在8086来返回DOS。而改用“先将程序段前缀的起始地址及数据段DS段首址和偏移地址AX存入堆栈,再用指令RET返回DOS的方法。所以,又定义了100个字节的堆栈段。同时堆栈段又为保存最后的进位位提供了条件。
●编写程序,可以想得到,需要MOV、MUL、ADD、ADC、PUSH、PUSHF和RET等指令。具体程序如下:来返回DOS。而改用“先将程序段前缀的起始地址及数据段DS段
NUME32bitMULTIPLY;程序名“32位乘法”DATASEGMENT;数据段定义开始MULNUMDW0000H,0FFFFH,0000H,0FFFFH,4DUP(?);DATAENDS;数据段定义结束STACKSEGMENTPARASTACK‘STACK’;堆栈段定义开始
DB100DUP(?);堆栈段长度为100字节STACKENDS;堆栈段定义结束CODESEGMENT;代码段开始
ASSUMECS:CODE,DS:DATA,SS:STACK;指定段寄存器STARTPROCFAR;图3-3程序流程图NUME32bitMULTIPLY;程序BEGIN:PUSHDS;将DS中包含的程序段前缀压栈保存 MOVAX,0;将0送AX,即设置AX的初值为0 PUSHAX;将DS中AX的偏移地址压栈,这三句即保存返回至DOS的段值和IP值。 MOVAX,DATA; MOVDS,AX
;将数据段首地址送DS
LEABX,MULNUM;将MULNUM的偏移地址送BX,定义了地址指针MULNUM32:MOVAX,[BX];被乘数的低16位B→AX
MOVSI,[BX+4];乘数的低16位D→SI
MULSI;B×D,部分积1的低位送AX,部分积1的
高位送DX,
MOV[BX+8],AX;保存部分积1的低位
MOV[BX+0AH],DX;保存部分积1的高位
MOVAX,[BX+2];被乘数的高16位A→AXBEGIN:PUSHDS;将DS中包含的程序段
MULSI;A×D,部分积2的低位送AX,部分积2的高
位送DX ADDAX,[BX+0AH];部分积1的高位+部分积2的低位 ADCDX,0;加入部分积1的低位的进位
MOV[BX+0AH],AX;保存部分积1的高位+部分积2的低位
MOV[BX+0CH],DX;保存部分积2的高位 MOVAX,[BX];被乘数的低16位B→AX
MOVDI,[BX+6];乘数的高16位C→DI MULDI;B×C,部分积3的低位送AX,部分积3的高位送DX ADDAX,[BX+0AH];部分积1的高位+部分积2的低位+部分
积3的低位
ADCDX,[BX+0CH];部分积2的高位+部分积3的高位+进位
MOV[BX+0AH],AX;保存部分积1的高位+部分积2的低位
+部分积3的低位
MULSI;A×D,部分
MOV[BX+0CH],DX;保存部分积2的高位+部分积3的高位+进位
PUSHF;将标志寄存器压栈,保存“部分积2的高位+部分积3的
高位+进位”的进位位
MOVAX,[BX+2];被乘数的高16位A→AX
MULDI;A×C,部分积4的低位送AX,部分积4的高位送DX
POPF
;弹出堆栈保存的“部分积2的高位+部分积3的高位+进位”
ADCAX,[BX+0CH];部分积4的低位+部分积2的高位+部
分积3的高位+进位
ADCDX,0;部分积4的高位+进位
MOV[BX+0CH],AX;保存“部分积4的低位+部分积2的高位
+部分积3的高位+进位”+进位
MOV[BX+0EH],DX;保存部分积4的高位+进位
RET
STARTENDP
CODEENDS
ENDBEGIN MOV[BX+0CH],
3.3
分支结构的汇编语言源程序的编写3.3.1
条件转移指令3.3.2
汇编语言分支结构程序的编写返回本章首页3.3分支结构的汇编语言源程序的编写3.3.1条件 在汇编语言程序设计中,常利用条件转移指令实现程序的分支。指令助记符是随条件变化而变化的,其构成方法是:第一个字母是J,紧接着的字母是标志寄存器的代号P、S、Z、……,表示“条件”,条件满足,则转移。例如JZ,表示结果为0,则转移;如果“条件”是否定的,就在已构成的两个字母间加字母N,例如JNZ,表示结果不为0,则转移。条件转移指令只有一个操作数,指出转移的目标地址,并且只能是一个短标号,即转移的偏移地址是8位的。 有一个条件转移指令JCXZ,构成方法较特殊,它的转移条件是寄存器CX的内容为0,而不是标志寄存器的某位的标志。
所有的条件转移指令都不影响标志位。3.3.1
条件转移指令 在汇编语言程序设计中,常利用条件转移指令实现程序的分支。指(1)根据单个标志的设置情况的转移指令。共五种10条: 1)JZ(或JE);上一步的结果为零(或相等)则转移。格式:JE(或JZ)标号测试条件:ZF=1 2)JNZ(或JNE);上一步的结果不为零(或不相等)则转移。格式:JNZ(或JNE)标号测试条件:ZF=0 3)JS;上一步的结果为负,则转移。格式:JS标号测试条件:SF=1
4)JNS;上一步的结果为正,则转移。现将所有的条件转移指令列举如下:(1)根据单个标志的设置情况的转移指令。现将所有的条件转移指格式:JNS标号测试条件:SF=0 5)JO;上一步的结果为溢出,则转移。格式:JO标号测试条件:OF=1 6)JNO;上一步的结果不为溢出,则转移。格式:JNO标号测试条件:OF=0 7)JP(或JPE);上一步的结果的奇偶标志位为1,则转移。格式:JP标号测试条件:PF=1 8)JNP(或JPO);上一步的结果的奇偶标志位为0,则转移。格式:JNP(或JPO)标号测试条件:PF=0 9)JC;上一步有进位或借位,则转移。格式:JNS标号格式:JC标号测试条件:CF=1 10)JNC;上一步无进位或无借位,则转移。格式:JNC标号测试条件:CF=0(2)比较两个无符号数,并根据比较结果的高低转移。
1)JAJNBE(或JNBE)高于,即不低于或等于,则转移。格式:JA(或JNBE)标号测试条件:CF=0且ZF=0 2)JNA(或JBE)不高于,即低于或等于,即则转移。格式:JBE(或JNA)标号测试条件:CF=0或ZF=1 3)JB(或JNAE,JC)低于,即不高于或等于,或进位为1则转移格式:JB(或JNAE,JC)标号格式:JC标号(2)比较两个无符号数,并根据比较结果的高 测试条件:CF=1 4)JNB(或JAE,JNC)不低于,或高于或等于,或进位为0则转移格式:同上测试条件:CF=0(3)比较两个带符号数,并根据比较的结果的大小转移。
1)JL(或LNGE)小于,或者不大于且等于,则转移。格式:JL(或JNGE)标号测试条件:SF异或OF=1 2)JNL(或JGE)不小于,即或者大于或者等于则转移。格式:JNL(或JGE)标号测试条件:SF异或OF=0 3)JLE(或JNG)小于或等于,即不大于则转移。格式:JLE(或JNG)标号测试条件:(SF异或OF)或ZF=1 测试条件:CF=1(3)比较两个带符号数,并根据比较的结果
4)JNLE(或JG)不小于或等于,即大于则转移。格式:JNLE(或JG)标号测试条件:(SF异或OF)或ZF=0(4)测试CX的值为0则转移指令格式:JCXZ标号测试条件:(CX)=0 4)JNLE(或JG)不小于或等于,即大于则转移。(4)测3.3.2汇编语言分支结构程序的编写在设计分支程序时必须注意以下几点:(1)正确选择分支形成的判定条件和相应的条件转移指令。
(2)对每个分支程序的入口,一定要给出标号,标明不同分支的转向地址。必须保证每条分支都有完整的结果。
(3)在检查和调试时必须对所有的分支进行,因为某几条分支正确,不足以说明整个程序是正确的。3.3.2汇编语言分支结构程序的编写在设计分支程序时必
分支结构程序的分类:
♦
简单的二分支结构程序
♦多分支结构程序分支结构程序的分类:1.简单的二分支结构设计举例【例3-7】把a,b两个8位数中较大的数赋值给max。●分析问题:这是典型的二分支结构。确定分支的条件是a>b吗?●确定算法:采用比较转移指令,在汇编语言中用AL来保存中间结果。因为读取寄存器比读取存储器要快,并且,汇编语言指令不允许两个操作数都为存储单元。●画程序流程图:画程序流程图,见图3-5。图3-5例3-7程序流程图1.简单的二分支结构设计举例【例3-7】把a,b两个8●确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义3个变量:两个数a、b,还有一个最大数max,都是8位数,应选DB类型,但考虑到执行CMP指令实际上是作减法,可能有借位的情况,故选DW类型。max尚属未知,故应定义一个字长的缓冲区。还要用到寄存器AL。●编写程序,可以想得到,需要MOV、CMP等指令。最后要返回DOS。具体程序如下:DATASEGMENT ;/定义数据段aDW?
;/定义字变量abDW?
;/定义字变量bmaxDW?
;/定义字变量maxDATAEDNS
;/数据段定义结束CODESEGMENT ASSUMECS:CODE,DS:DATA●确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架START:MOVAX,DATA
MOVDS,AXMOVAL,aCMPAL,b;/比较a和b,产生分支
JAEXIT;/如果a>b,则跳转到EXIT语句,否则,执行下列语句MOVAL,b;/送b到寄存器EXIT:MOVmax,AL;/送(AL)到存储单元max
MOVAH,4CH;INT21H;/返回DOSCODEENDS;/代码段结束
ENDSTART;/程序结束START:
2.多分支结构程序设计多分支结构程序设计比较复杂一些。关键是怎样根据条件对多分支进行判断,确定不同分支程序转移的入口地址。方法有:(1)逻辑分解流程图法
根据逻辑分解流程图,按照判别条件的先后,逐个进行判断和转移。设分支条件为X1,X2,……,XN,则逻辑分解流程图为3-6所示。
图3-6逻辑分解流程图2.多分支结构程序设计多分支结构程序设计比较复杂一些。关键【例3-8】试编写执行符号函数
的程序。●分析问题:由题意可知,这是多分支结构。本题有三个分支:X>0、X=0和X<0。按照逻辑分解的方法,可以先将其归并为两个条件:X≥0和X<0,由此形成两个分支;再将分支X≥0分解为X>0和X=0,各分支均用条件转移指令来实现。●确定算法:采用比较转移指令。●画程序流程图:画程序流程图,见图3-7。●确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义2个变量:两个数X和Y,由题设为8位数,应选DB类型,但考虑到执行CMP指令实际上是作减法,可能有借位的情况,故选DW类型。假设任意给定的X值存放在XX单元,函数Y的值存放在YY单元。●编写程序,可以想得到,需要MOV、CMP和程序转移等指令。【例3-8】试编写执行符号函数最后要返回DOS。
具体程序如下:DATASEGMENT ;/定义数据段
XXDW;/定义字变量X
YYDW?;/定义字变量Y
DATAEDNS;/数据段定义结束CODESEGMENT ASSUMECS:CODE,DS:DATASTART: MOVAX,DATA MOVDS,AX;/给DS赋值
MOVAL,XX;
CMPAL,0;/XX与零比较
开始(AL)←XX(AL)≥0(AL)>0(AL)←1结束YN图3-7例3-8程序流程图(AL)←-1(AL)←0YN最后要返回DOS。
具体程序如下:DATASEGMENTJGEBIGR;/X=(AL)≥0,则转移到BIGR语句
MOVAL,0FFH;/否则,X<0时,将–1送入AL JMPEQUL;/无条件转移语句,转移到EQUL语句
BIGR:JEEQUL;/X=0,则转移到EQUL语句
MOVAL,1;/X>0时,将1送入AL
EQUL:MOVYY,AL;/无论结果如何,都将(AL)送入YY单元
HLT;/暂停(2)跳转地址表法
如果各分支的判定结果可以用一个寄存器的不同的有序的值来表示,则可将各分支程序的入口地址与寄存器的不同的有序的值一一对应,列入一张表中,此表称为跳转地址表。JGEBIGR;/X=(AL)≥0,如图3-8所示。各分支程序的入口地址的计算公式是:
各分支程序的入口地址=寄存器的值×2+跳转地址表首地址
这种利用跳转地址表实现多分支程序的转移的方法,称为跳转地址表法。图3-8分支程序入口地址表如图3-8所示。各分支程序的入口地址的计算公式是:【例3-9】根据AL中的被置位的情况来控制转移到8个分支程序R1~R8中的一个(在中断响应时,通过软件查询,从而转到相应的中断服务程序入口就类似于这种情况)。
如果AL中为00000001则转至R1
如果AL中为00000010则转至R2
如果AL中为00000100则转至R3
如果AL中为00001000则转至R4
如果AL中为00010000则转至R5
如果AL中为00100000则转至R6
如果AL中为01000000则转至R7
如果AL中为10000000则转至R8
实现上述要求的程序框图如图3-9所示。我们可以把8个子程序的入口地址编成如图3-8所示的分支程序入口地址表。根据流程图可以写出如下程序:【例3-9】根据AL中的被置位的情况来控制转移到8个分支程序●分析问题:由题意可知,要求根据某种条件实现8个分支程序●确定算法:采用跳转地址表法(见图3-8分支程序入口地址表),结合条件转移指令来实现。●画程序流程图:见图3-9。●确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架要三个段:数据段、堆栈段和代码段。数据段中创建分支程序入口地址表,应选DW类型,使用寄存器BX定位。●编写程序,可以想得到,需要MOV、JMP、JC、INC、LEA和PUSH等指令。最后要返回DOS。未想到的,在编写过程中根据需要随时添加,如RCR指令等。
具体程序如下:
NAMEBRANCH_PROGDATASEGMENT●分析问题:由题意可知,要求根据某种条件实现8个分支程序BRTABDWR11;/开始创建分支程序入口地址表。第一步创建分支程序R1入口地址的IP值 DWR12;/创建分支程序R1入口地址的码段值
DWR21;/仿DWR11,下同
DWR22;/仿DWR12,下同
DWR31
DWR32
DWR41
DWR42
DWR51
DWR52
DWR61
DWR62
DWR71
DWR72
DWR81
DWR82图3-9分支程序转移流程图BRTABDWR11;/开始创建分支程序入口地址DATAENDSSTACKSEGMENTPARASTACK'STACK'
DB100DUP(?);/定义一个100个字节的堆栈空间TOPEQU$-STACK;/栈顶的地址为程序的当前地址与堆栈首地址的差。STACKENDSCODESEGHENTSTARTPROCFAR
ASSUMECS:CODE,DS:DATA,SS:STACKBEGIN:PUSHDS;/将数据段首址压栈
MOVAX,0;/将寄存器AX清零
PUSHAX;/使程序能返回DOS
MOVAX,DATA
MOVDS,AX;/将DATA段首址(即分支程序入口地址表)送寄存器DSDATAENDS
MOVAX,STACK;
MOVSS,AX;/将堆栈段首址送寄存器SS
MOVAX,TOP
MOVSP,AX;/将堆栈段栈顶地址送堆栈指针寄存器SP
LEABX,BRTAB;/设跳转表的地址指针GTBIT:RCRAL,l;/通过进位循环右移
JCGETAD;/在循环右移过程中顺序检查AL中各位的状态
INCBX;/BX自动加1
INCBX;/BX自动加1,移到下一分支
INCBX;/BX自动加1
INCBX;/BX自动加1,完成寄存器的值×2
JMPGTBITGETAD:JMPDWORDPTR[BX];/段间间接转移STARTENDPCODEENDS
ENDBEGIN MOVAX,STACK;(3)跳转指令表法
跳转指令表法的思路与跳转地址表法基本相同,不同的只是它是在代码段中把转移到各个分支程序段的跳转指令放在一个表中,该表就称为“跳转指令表”。表内跳转转移指令的地址的计算公式:
表内跳转指令表的地址=(编号-1)×2+跳转指令表的首地址
=编号×2-2+跳转指令表的首地址(3)跳转指令表法跳转指令表法的思路与跳转地当
N=1时,显示信息(DSPLAY); N=2时。传送信息(TRAN); N=3时。处理信息(PROCl); N=4时,打印信息(PRTN); N=5时。结束程序(EXIT).
相应的处理为一独立的程序段,它们的入口地址分别为DSPLAY,TRAN,PROCl,PRIN,EXIT。当这些程序处理结束时仍返回读入N。只有当N=5时程序才结束。
试利用跳转指令表的分支程序实现这些要求。【例3-10】由键盘输入一个数N,当N为不同值时应作不同处理当N=1时,显示信息(DSPLAY);【例3●分析问题:由题意可知,这是一个五分支程序。它们的入口地址分别为DISPLAY,TRAN,PROCl,PRIN,EXIT。当这些程序处理结束时仍返回读入N。只有当N=5时程序才结束.●确定算法:构建跳转指令表,采用通过执行跳转指令表中相应的跳转指令,就可以转移到不同的分支。●画程序流程图:略。●确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:堆栈段和代码段。堆栈段中定义一个256个字的缓冲区,当然是DW类型,再定义一个字类型的栈顶,用栈顶指针SP定位。采用寄存器AL,AX存数字,寄存器BX存跳转指令的地址。●编写程序,可以想得到,需要MOV、JMP、LEA、SUB、ADD、CMP和JB、JA、CBW等指令。最后要返回DOS。未想到的,在编写过程中根据需要随时添加,如SHL指令等。为了简化程序,每段处理程序除了EXIT以外仅给出了一条转移指令表示当某项处理完成后返回AGAIN继续从键盘读入一个字符直到输入字符为‘5’●分析问题:由题意可知,这是一个五分支程序。它们的入口地址分为止。例中存放转移指令的表JADT2在代码段中。具体程序如下:STACKSBGMENTSTACK DW256DUP(?);/在堆栈中,定义一个256个字的数据缓冲区TOPLABELWORD;/定义栈顶变量TOP,字类型STACKENDSCODESEGMENT ASSUMECS:CODE,SS:STACKSTART:MOVAX,STACK;
MOVSS,AX;/堆栈段寄存器SS初始化
MOVSP,OFFSSETTOP;/送栈顶的偏移地址到寄存器SPAGAIN:
MOVAH,01;/(AH)=01,1号功能(键盘输入)调用为止。例中存放转移指令的表JADT2在代码段中。
INT2lH;/DOS功能调用 SUBAL,30H;/将键盘输入的数字字符的ASCII码减去
数字字符“0”的ASCII码“30H”,求出输入
数字的二进制表示的值,放在AL中
CMPAL,01;/与“1”比较输入数字的值
JB,AGAIN;/若输入数字的值比1小,返回程序AGAIN,
由键盘重新输入。若输入数字的值比1大,接
着执行下一指令
CMPAL,05;/与“5”比较输入数字的值
JAAGAIN;/若输入数字的值比5大,返回程序AGAIN,
由键盘重新输入。若输入数字的值比1大,比
5小,接着执行下一指令
SHLAL,01;/将放在AL中的输入数字的二进制表示,逻
辑左移1位。依据计算跳转转移指令地址的
公式:先作编号×2 INT2lH;/
CBW;/将AL中的8位数扩展为16位数,放在寄存器AX中
MOVBX,OFFSSETJADT2;/送转移指令跳转表的首地址
送寄存器BX
ADDBX,AX;/依据计算跳转转移指令地址的公式再作:编
号×2+跳转指令表的首地址
SUBBX,02;/继续计算,将上一步的结果减去2,完成计算
JMPBX;/跳转到BX指示的跳转指令的地址JADT2JMPSHORTDISPLAY:/跳转表
JMPSHORTTRAN
JMPSHORTPROCl
JMPSHORTPRTN
JMPSHORTEXITDISPLAY:…… CBW;/将AL中的8位数扩展为16位
JMPAGATNTRAN:
…… JMPAGAINPROCl:
…… JMPAGAINPRIN:
…… JMPAGAINEXlT:MOVAH,4CH INT2lHCODEENDS ENDSTART JMPAGATN3.4
循环结构的汇编语言源程序的编写3.4.1循环控制指令3.4.2程序的循环结构3.4.3控制程序循环的方法3.4.4多重循环返回本章首页3.4循环结构的汇编语言源程序的编写3.4.1循环控(1)
循环指令的作用:根据条件满足与否,完成一串重复的操作,形成循环程序。(2)循环指令有3条,且3条指令都是短转移(short-label表示短标号)指令。
循环转移指令LOOP格式:LOOP目标标号测试条件与功能:(CX)不等于0,则(CX)←(CX)–1;(IP)←(IP)+8位偏移量。3.4.1循环控制指令(1)循环指令的作用:3.4.1循环控制指令说明:LOOP指令相当于下面两条指令的组合: DECCX JNZshort-label;short-label表示短标号相等(为零)循环转移指令LOOPZ/LOOPE格式:LOOPZ(或LOOPE)目标标号测试条件与功能:(CX)等于0且ZF=1,则(CX)←(CX)–1;(IP)←(IP)+8位偏移量。LOOPNZ/LOOPNE循环指令格式:LOOPNZ(或LOOPNE)目标标号测试条件与功能:(CX)不等于0且ZF=0;则(CX)←(CX)–1;(IP)←(IP)+8位偏移量。说明:LOOP指令相当于下面两条指令的组合:【例3-11】将数据区的数据按正、负分开,分别送到两个缓冲区,程序如下:START:MOVSI,OFFSETBLOCK;/将数据区的偏移地址送
SI,即将
SI指向数据区
MOVDI,OFFSETPLUS-DATA;/DI指向正数缓冲区
MOVBX,OFFSETMINUS-DATA;/BX指向负数缓冲区
MOVCX,COUNT;/将数据字节送CXCLD;/将DF清0GOON:LODSB;/取串指令
TESTAL,80H;/字节最高位为1(表示是负数)吗?
JNZMINUS;/是,则转移到MINUS语句
STOSB;/否则,执行存入串指令STOSB
JMPAGAIN;/跳转到AGAIN语句MINUS:XCHGBX,DI;STOSB;XCHGBX,DIAGAIN:LOOPGOONHLT【例3-11】将数据区的数据按正、负分开,分别送到两个缓冲区
3.4.2
程序的循环结构一个完整的循环结构程序由以下几部分组成:
1.循环初态设置部分:这是为了保证循环程序能正常运行而必须作的准备工作,在循环开始时往往要给循环过程置以初态,即赋一个初值。循环初态又可以分成两部分,一是循环工作部分初态,另一是循环结束条件的初态。例如,要设地址指针,要使某些寄存器清零,或设某些标志等等。循环结束条件的初态往往置以循环次数.置初态也是循环程序的重要的一部分,不注意往往容易出错。
2.循环体:就是要求重复执行的程序段部分。其中又分为:循环工作部分和循环调整部分。循环调整部分修改循环参数,以保证每次循环所完成的功能不是完全重复的。
3.循环结束条件部分:也称循环出口判定部分。在循环程序中必须给出循环结束条件,否则程序就会进入死循环。每循环一次检查循环结束的条件,当满足条件时就停止循环,往下执行其他程序。 3.4.2程序的循环结构一个完整的循环结构程序由以下几
3.4.3控制程序循环的方法
控制程序循环的方法就是选择循环控制条件,是循环程序设计的关键。
常用的循环控制方法有计数控制法、条件控制法和逻辑尺控制法等。1.计数控制法
常见的循环是计数循环,当循环了一定次数后就结束循环。在微型机中,常用一个内部寄存器(一般用CX),或寄存器对作为计数器,对它的初值置循环次数,每循环一次减1,当计数器的值减为0时,就停止循环。也可以初值置为0,每循环一次加l,再与循环次数相比较,若两者相等就停止循环。 3.4.3控制程序循环的方法控制程序循【例3-11】编写一个程序,计算SUM=A1×B1+A2×B2+…+An×Bn。设A1,A2,…,An和B1,B2,…,Bn为无符号数,假定SUM不会超过65535。●分析问题:由题意可知,这是求n个数的累加和,而每个数都是两个数组对应项的乘积,存在n次重复操作。●确定算法:采用采用比较循环指令,循环次数是n次。故用循环次数作为循环的控制条件,再配合使用LOOP指令。循环控制采用计数控制。●画程序流程图:略。●确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义4个变量:两个数组变量A和B,由题设知为8位数,应选DB类型,使用寄存器SI定位。和数SUM变量,由题设知为16位数,选DW类型,其中间结果放在寄存器BX。还有一个数N,为循环次数,计数器用CX。【例3-11】编写一个程序,计算SUM=A1×B1+A2×●编写程序,可以想得到,需要MOV、ADD、MUL、INC和LOOP等指令。最后要返回DOS。未想到的,在编写过程中随时添加,如XOR指令等。具体程序如下:DATASEGMENT
ADBA1,A2,…,An;/定义变量A
BDBB1,B2,…,Bn;/定义变量B
SUMDW?;/定义变量SUM,其值待求
NEQUB-A;/定义变量N,为循环次数DATAENDSCODESEGMENT ASSUMECS:CODE.DS:DATA START:MOVAX,DATA MOVDS,AX●编写程序,可以想得到,需要MOV、ADD、MUL、IN XORBX,BX;/准备存放和的寄存器BX清零,设置工作初值
XORSI,SI;/变量A和B的地址定位寄存器SI清零,设置工作初值
MOVCX,N:/为循环次数寄存器CX设置循环控制初值NLOPl:MOVAL,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年怀化职业技术学院单招职业倾向性测试必刷测试卷带答案解析
- 2026年朔州职业技术学院单招职业适应性考试必刷测试卷及答案解析(夺冠系列)
- 2026年九江职业技术学院单招职业适应性考试题库带答案解析
- 2026年咸阳职业技术学院单招职业适应性考试必刷测试卷附答案解析
- 2026年浙江旅游职业学院单招综合素质考试必刷测试卷及答案解析(名师系列)
- 2026年上饶幼儿师范高等专科学校单招职业技能考试题库带答案解析
- 房屋抵账转让协议书
- 房屋拖管公司协议书
- 房屋期权买卖协议书
- 房屋清洁赔偿协议书
- 大模型在企业的应用实践
- 2025年河南省体育彩票管理中心公开招聘合同制聘用人员50人笔试考试备考题库及答案解析
- 2025年河北机关事业单位工人技能等级考试题库(含答案)
- 七上课外古诗词诵读《潼关》课件
- 地铁自动化检修员面试题及答案
- 数学新教材八年级上册解读课件(北师大版2024)
- 学全体教职工大会校长讲话:35 分钟会议把所有老师“点醒”到位
- 修理修配劳务合同范本
- 12.2 正确对待顺境和逆境 课件-2025-2026学年统编版道德与法治七年级 上册
- 2025年车险试题及答案
- 2025至2030伴侣动物内寄生虫行业发展研究与产业战略规划分析评估报告
评论
0/150
提交评论