汇编语言第四章 程序设计的基本方法.docx
- 文档编号:12197129
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:31
- 大小:538.66KB
汇编语言第四章 程序设计的基本方法.docx
《汇编语言第四章 程序设计的基本方法.docx》由会员分享,可在线阅读,更多相关《汇编语言第四章 程序设计的基本方法.docx(31页珍藏版)》请在冰豆网上搜索。
汇编语言第四章程序设计的基本方法
第四章程序设计的基本方法
汇编语言程序中,最常见的几种程序结构形式:
顺序程序、分支程序、循环程序、子程序。
转移指令
分支程序的设计
循环程序设计,循环指令
堆栈的概念,进栈、出栈指令
子程序的定义、调用、返回;主程序与子程序的参数传递
4.1转移指令
特点:
改变程序的执行顺序,即改变了指令指示器IP的内容。
4.1.1条件转移
功能:
由上一条指令所设的条件码来判别测试条件,满足条件则转移到指令所指地址去执行,否则循环执行。
满足条件时,当前(IP)+符号扩展到16位的位移量→IP。
位移范围在-128~127之间。
一、根据标志位转移
1.CF标志:
JC/JNC
JC表示:
CF=1时转移。
例如两数相减,低于。
JNC表示:
CF=0时转移。
例如两数相减,高于或等于。
2.ZF标志:
JZ/JNZ
JZ表示:
结果为0,转移,此时ZF=1。
JNZ表示:
结果不为0,转移,此时ZF=0。
3.SF标志:
JS/JNS
JS表示:
结果为负,转移,此时SF=1。
JNZ表示:
结果不为正,转移,此时SF=0。
4.OF标志:
JO/JNO
JO表示:
结果溢出,转移,此时OF=1。
JNO表示:
结果不溢出,转移,此时OF=0。
5.PF标志:
JP/JNP或JPE/JPO
JP表示:
低8位中1的个数为偶数时转移,此时OF=1。
JNP表示:
低8位中1的个数为奇数时转移,此时OF=0。
如:
两数相加,结果为0,则转移到P2,否则运行P1。
二、无符号数的条件转移
此指令跟在比较指令之后,比较的对象为无符号数。
结果有:
高于、高于等于、低于、低于等于。
Above:
高于,below:
低于,equal:
等于。
1.JA/JNBE
JA表示:
高于则转移。
JNBE表示:
不低于或等于转移。
测试条件:
CF∨ZF=0。
(分析:
a-b≥0,此时CF=0;a-b≠0,此时ZF=0。
)
2.JAE/JNB
JAE表示:
高于等于则转移。
JNB表示:
不低于则转移。
测试条件:
CF=0或ZF=1。
3.JB/JNAE
JB表示:
低于则转移。
JNAE表示:
不高于且不等于则转移。
测试条件:
CF=1。
4.JBE/JNA
JBE表示:
低于等于则转移。
JNA表示:
不高于则转移。
测试条件:
CF∨ZF=1。
三、带符号数条件转移
比较结果分为4种:
大于、大于等于、小于、小于等于。
Great:
大于,Little:
小于,Equal:
等于。
1.JG/JNLE
JG表示:
两数相比,大于,则转移。
JNLE表示:
两数相比,不小于且不等于,则转移。
测试条件:
(SF
OF)∨ZF=0。
2.JGE/JNL
JGE表示:
两数相比,大于等于,则转移。
JNL表示:
两数相比,不小于,则转移。
测试条件:
SF
OF=0。
3.JL/JNGE
JL表示:
两数相比,小于,则转移。
JNGE表示:
两数相比,不大于且不等于,则转移。
测试条件:
SF
OF=1。
4.JLE/JNG
JLE表示:
两数相比,小于等于,则转移。
JNG表示:
两数相比,不大于,则转移。
测试条件:
(SF
OF)∨ZF=1。
使用转移指令时应注意:
注意:
●CMP比较指令本身无法分别有、无符号数,它比较的是否有符号,由后面的转移指令确定。
例:
MOVAL,-40H
CMPAL,50H
JGL1;比较的是有符号数,(-40H)<50H,不转移
…
L1:
…
若将JG换为JA,就变成无符号数了,此时,(AL)=(-40H)补=C0H>50H,转移。
●转移指令的转移范围-128~127。
4.1.2无条件转移指令
功能:
无条件地转移到目的地址执行。
可以分为两类:
段内、段间。
1.段内直接近转移
格式:
JMPNEARPTR标号;
功能:
(IP)+16位偏移量→IP。
转移范围32K。
2.段内间接转移
格式:
JMPWORDPTROPD;
功能:
(OPD)→IP。
如:
JMPWORDPTR[BX+TABLE]
作用:
([BX+TABLE])→IP,偏移地址[BX+TABLE]所指单元的内容送IP。
假定:
(DS)=2000H,(BX)=1256H,TABLE=20A1H,(232F7H)=3280H。
则:
PA=(DS)左移4位+(BX)+TABLE=232F7H
执行后:
(IP)=3280H
3.段间直接转移
格式:
JMPFARPTR标号;
功能:
标号的偏移地址→IP,标号所在段地址→CS。
如:
4.段间间接转移
格式:
JMPDWORDPTROPD
功能:
(OPD)→IP,(OPD+2)→CS。
如:
JMPDWORDPTR[BX]
([BX])→IP,([BX]+2)→CS。
注意是偏移地址[BX]所指内容。
4.2分支程序设计
特点:
计算机根据不同情况自动作出判断,有选择地执行相应处理程序。
一、两种结构形式
结构特点:
运行方向是向前的,条件确定,只能执行分支中的一个。
二、程序设计方法
程序分支一般用条件转移指令产生,不同条件是通过FLAGS的标志状态反映出来。
注意:
转移指令不影响条件码特性,也就是可以连续使用转移指令,使程序产生多个分支。
如:
CMPARRAY[BX],0
JLEL1;小于等于0,转移到L1
…;分支1
L1:
JLNEXT;小于0,转移到NEXT
…;分支2
NEXT:
…
4.2.1举例
例1.比较数组BUF中的三个16位补码,若三个数都不相等则显示0,有两个相等则显示1,都相等则显示2。
分析:
假定三个数为a、b、c,D为比较结果。
我们可以画出流程图:
例2.设A、B、C三个单元存放着三个数,若三个数都不为0,则求三数之和放在D单元内,若其中有一个为0,则将另外两个也清0。
分析:
此题为判断A、B、C三个数是否为0的分支程序。
存贮单元的分配,题目已告诉,变量名分别为A、B、C、D,都为字变量。
根据要求画出流程图:
分支程序设计应注意:
●选择合适的转移指令
如:
CMPAX,1
JLL1
JL为有符号转移指令,(AX)<1则转移。
若JL换为JB,则为无符号转移指令,该转移的反而不转移。
●为每个分支安排出口
如:
实现(AL)≥0,′+′→DL;
(AL)<0,′-′→DL;
CMPAL,0
JGEL1;有符号比较,大于等于转L1
MOVDL,‘-’
JMPEXIT;若无此句,无论AL为何,DL=‘+’
L1:
MOVDL,‘+’
EXIT:
…
●将分支中的公共部分尽量放到分之前或分支后,使程序尽量短。
如:
●按流程图编程
分支先后次序应尽量与问题提出的先后次序一致。
●假定各种输入,调试分支程序。
4.3循环程序设计
4.3.1循环程序的结构
循环程序有两种结构形式:
上述两种结构的循环程序,由三个部分组成:
(1)设置循环的初始状态
置循环次数计数值以及循环体正常运行的初始状态值。
(2)循环体
由循环的工作部分和修改部分组成。
其中,工作部分完成程序功能;修改部分保证循环时,参加执行运行的信息发生规律性变化。
(3)循环控制部分
保证循环程序按规定的次数或特定条件正常循环。
4.3.2循环控制方法
一、计数控制
特点:
用于循环次数已知的情况。
1.正计数法
特点:
计数值开始为0,每次循环加1,直到加到n为止。
如:
MOVCX,0;初始化
…
L1:
…;循环体
INCCX
CMPCX,n;控制部分
JNEL1
…
2.倒计数法
分两种情况:
二、条件控制
特点:
循环次数事先不知道。
如:
求AX中1的个数。
一般方法,逐位比较。
…
MOVBL,0;BL中存放1的个数
MOVCL,16
L1:
SALAX,1;算术左移,b15→CF
JNCL2
INCBL;CF=1,(BL)+1→CL
L2:
DECCL
JNZL1
…
上述方法必须循环16次。
…
MOVCL,0;CL中存放1的个数
L:
ANDAX,AX;产生条件
JZEXIT
SALAX,1;算术左移,b15→CF
JNCL
INCCL;CF=1,(CL)+1→CL
JMPL
EXIT:
…
注意:
第二种方法不用循环16次就可以求得1的个数。
三、循环转移指令
1.LOOP标号
功能:
(CX/ECX)−1→CX/ECX
若(CX/ECX)不为0,则转标号处执行。
基本等价于:
DECCX/ECX
JNZ标号
注意:
LOOP指令对标志位无影响!
2.LOOPE/LOOPZ标号
功能:
(CX/ECX)−1→CX/ECX
若(CX/ECX)不为0,且ZF=1,则转标号处执行。
注意:
等于或为0循环转移指令,本指令对标志位无影响。
例:
MOVCX,10
MOVBX,OFFSETBUF-1
L3:
INCBX
CMPBYTEPTR[BX],0
LOOPEL3
3.LOOPNE/LOOPNZ标号
功能:
(CX/ECX)−1→CX/ECX
若CX/ECX)≠0,且ZF=0,则转标号处执行
4.JCXZ标号/JECXZ标号
功能:
若(CX/ECX)为0,则转标号处执行。
先判断,后执行循环体时,可用此语句,标号为循环结束处
4.3.3单重循环程序设计
特点:
循环体内不再包含循环结构。
1.循环次数已知
对于循环次数已知的情况,通常采用计数控制方法实现循环。
例1:
将BUF中定义的16位二进制数用十六进制数的形式显示在屏幕上。
分析:
16位二进制数,每4位一组在屏幕上显示。
用循环结构可以完成,每一个循环显示一个十六进制数,因此,循环次数已知,为4。
循环中包含十六进制数与ASCII码字符的转换。
流程:
2.最大循环次数未知
特点:
用条件来控制循环。
例:
将字变量Y中1的个数存入COUNT单元中。
分析:
用移位的方法,将每位数移到最高位,如果Y=0就结束;如果为负数,则表示最高位为1。
流程图:
4.3.4多重循环程序设计
特点:
循环体内还套有循环。
设计原则:
由外向里逐层设计,分别考虑各层控制条件。
例:
以BUF为首址的字节存贮区,存放着n个无符号数,请将数组按从小到大排序。
分析:
对这类问题采用逐一比较算法。
从第一个数开始,依次对相邻的两个数进行比较,若次序不对(由小到大),则两数互换位置,否则不作任何操作。
序号
数
第1遍
第2遍
第3遍
第4遍
1
8
3
3
3
3
2
5
8
4
4
4
3
7
7
8
5
5
4
4
5
7
8
7
5
3
4
5
7
8
比较次数:
(假定n个数)
第1遍:
n-1次比较,第1小数到位置1;
第2遍:
n-2次比较,第2小数到位置2;
…
第i遍:
n-i次比较,第i小数到位置i;
上述的5个数,4遍就排好了。
因此n个数,最多n-1遍就可以排好。
有规律:
第1遍找到第1小的数,放到第1单元;
第2遍找到第2小的数,放到第2单元;
…
第i遍找到第i小的数,放到第i单元。
最多的遍数为n-1。
设i表示遍数,最多为n-1。
将i和j用寄存器表示:
i=SI,初值为1;j=DI,初值为i+1。
AL用来存放Xi。
注意:
数组X1、X2、…Xn,第i个数在BUF+i–1处。
综合上两个框图:
注意:
●外循环重复了n-1次;
●判断转移语句用的是无符号数转移指令;
●若要按从大到小排序,则只改变:
JBENEXT为JAENEXT。
4.4堆栈
堆栈:
主存中的一片数据存贮区。
为什么要用堆栈?
程序中经常用到子程序或处理中断,此时,主程序需要把子程序或中断程序将用到的寄存器内容保护起来,以便子程序或中断返回后,主程序能够从调用点或中断点处继续执行。
几个概念:
●压入:
数据进栈
●弹出:
数据出栈
●栈底:
堆栈的固定端
●栈顶:
栈指针指示的最后存入数据的单元
堆栈中数据的存取原则:
先进后出
例如:
注意:
●一端固定,一端活动
●存取“先进后出”
●只能是字单元
●最大64K
●SP栈顶指针
●SP由高地址向低地址移动
1.进栈指令
PUSHOPS
OPS:
寄存器、段寄存器、存储器
功能:
将OPS的字数据压入堆栈。
进栈活动:
(1)(SP)-2→SP
(2)(AX)→[SP]
2.出栈指令
POPOPD
OPD:
寄存器、段寄存器(除CS)、存储器
功能:
将栈顶元素弹出到某一寄存器(OPD)。
出栈活动:
(1)([SP])→BX
(2)(SP)+2→SP
例如:
假定(AX)=1234H,(BX)=5678H,(CX)=9ABCH
执行:
PUSHAX
PUSHBX
PUSHCX
POPDX
POPAX
结果:
(DX)=9ABCH
(AX)=5678H
(BX)=5678H
(CX)=9ABCH
3.8个16位寄存器进出栈指令
格式:
PUSHA
功能:
将8个16位寄存器按AX、CX、DX、BX、SP、BP、SI、DI顺序入栈
格式:
POPA
功能:
将8个16位寄存器按相反顺序出栈
4.8个32位寄存器进出栈指令
格式:
PUSHAD
功能:
将8个16位寄存器按EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI顺序入栈
格式:
POPAD
功能:
将8个32位寄存器按相反顺序出栈
4.5子程序设计
子程序又称为过程,相当于高级语言中的过程和函数。
4.5.1子程序的概念
一个程序中常常有类似的程序段,这些程序段的功能和结构相同,只是某些变量的赋值不同,此时把这些程序段写成子程序的形式,以便需要时调用它。
子程序的特点:
(1)分类
●用户自定义的子程序;
●系统子程序,作为系统软件的一部分供用户调用。
(2)与主程序的关系
是调用关系,调用之后又回到调用处的下一条指令。
(3)子程序是模块化编程的重要手段。
本节主要解决编制、调用、返回、参数传递等问题。
4.5.2子程序的调用和返回
一、调用指令CALL
调用范围:
段内:
属性定义为NEAR,调用寻址方式为直接。
段外:
属性定义为FAR,调用寻址方式为间接。
1.段内直接
格式:
CALL过程名
功能:
(IP)→↓(SP),目的地址EA→IP。
特点:
不保存CS到堆栈中。
2.段间直接
格式:
CALLFARPTR过程名
功能:
(CS)→↓(SP),(IP)→↓(SP);
目的地址EA→IP,目的地址的段首址→CS。
3.段内间接
格式:
CALLWORDPTROPD;
功能:
(IP)→↓(SP),(OPD)→(IP);
如:
…
MOVBX,OFFSETB
…
CALLWORDPTR[BX]
…
SUB1PROC
…
B:
MOVAX,1
…
RET
SUB1ENDP
4.段间间接
格式:
CALLDWORDPTROPD;
功能:
当前(CS)→↓(SP),(IP)→↓(SP);
改变为(OPD+2)→CS,(OPD)→IP。
二、返回指令RET
功能:
返回到调用指令的下一条指令处继续执行。
格式:
RET
RETn
具体功能:
对段间返回↑(SP)→IP,↑(SP)→CS。
对段内返回↑(SP)→IP。
注意:
●CALL和RET不影响标志位。
●对于RETn表示返回时,清除堆栈中栈顶的n个字。
4.5.3子程序定义格式及现场保护方法
一、定义格式
子程序名PROCNEAR或FAR
…
子程序名ENDP
二、现场保护与恢复
调用子程序时,有可能破坏原来寄存器的内容,因此,必须保护、恢复现场。
如:
子程序用到BX、AX寄存器的保护与恢复。
APROC
PUSHBX
PUSHAX
…;子程序
POPAX
POPBX
RET
AENDP
4.5.4主程序与子程序的参数传递
参数传递:
主程序为子程序提供入口参数,子程序返回结果给主程序。
一、寄存器法
利用寄存器传送入口、出口参数,适合于参数少的情况。
该方法较简单,就象功能调用入口参数一样。
二、约定单元法
入、出口参数在事先约定的存贮单元中。
适合于参数多的情况。
三、堆栈法
利用堆栈传递参数。
缺点是进出栈多,容易出错。
如:
将堆栈中的两元素相加。
入口为栈顶和次栈顶的两个元素。
4.5.5子程序及调用举例
例:
关于十进制到十六进制的转换。
从键盘输入一个十进制数,然后把该数以十六进制形式显示在屏幕上。
分析:
(1)用子程序DECIBIN实现从键盘上取十进制数并转换为二进制。
(2)用子程序BINIHEX把二进制数以十六进制数的形式在屏上显示。
(3)用CRLF子程序取得回车换行效果。
参数传递通过BX完成。
流程图:
程序运行后,输入:
234↙,在另外一行显示:
EA。
4.5.6子程序的嵌套
子程序中又调用另外一个子程序叫做子程序嵌套。
嵌套的层次不限。
嵌套的层次叫深度。
如:
注意:
●子程序中的CALL和RET应正确使用。
●在寄存器的保护、恢复时,避免层次之间因寄存器冲突而出错。
例:
在数据区中有10个不同信息,编号为0~9,每个信息包括30个字符。
编程实现:
从键盘接收0~9之间的一个编号,然后显示对应编号的信息。
分析:
将10个信息组成一个信息表,根据输入的编号,查表显示对应内容,显示时,调用子程序DISPLAY,显示字符也调用一个子程序DISPCHAR。
流程图:
第二次上机
一、目的
掌握分支、循环程序设计。
二、题目
以十进制形式输出有符号字数组BUF中每个元素的值:
负数前面需要输出符号,正数前面不需要符号。
各个值之间以空格隔开。
第三次上机
一、目的
掌握子程序设计。
二、题目
1.已知array1字数组中存放着n个无符号数。
编写子程序,分别求这n个数的平均值、最大值、最小值,并输出这n个数以及所求结果。
2.用模块化编程实现,将主程序放在一个模块中;将平均值、最大值、最小值函数放在一个模块中;将显示输出放在另一个模式中。
3.选做:
用堆栈法传递参数。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言第四章 程序设计的基本方法 汇编语言 第四 程序设计 基本 方法