【文档说明】第4章汇编语言程序设计li课件.ppt,共(65)页,908.513 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-44753.html
以下为本文档部分文字说明:
14.2.4过程定义伪指令PROC、ENDP过程就是子程序。一个过程可以被其它程序所调用(用CALL指令),过程的最后一条指令一般是返回指令(RET)。过程定义伪指令的格式为<过程名>PROC[类型]……RET<过程名>ENDP注意:PROC
和ENDP必须成对出现。2过程的类型有两种:NEAR——(默认类型)表示段内调用FAR——表示段间调用调用一个过程的格式为:CALL<过程名>3过程调用和返回指令过程(子程序)一段具有特定功能的,供其它程序调用的
公用程序。特点调用子程序时,IP(CS)的内容被压入堆栈栈顶。从子程序返回时,栈顶的内容又被弹出到IP(CS)。子程序执行结束后一般均要返回调用程序。一次定义,多次调用;可带参数调用,以完成不同的功
能。优点程序代码短,结构清晰,便于编程、调试、修改和阅读。两条相关指令:子程序调用指令CALL子程序返回指令RET4一般格式:CALLsub;sub为子程序的入口根据子程序入口的寻址方式,子程序调用有四类。①段内直接调用子程序的偏移地址直接
由CALL指令给出。格式:CALLnear_procCALL执行时,它首先将IP内容压栈,然后把指令中给出的位移量加到IP上。注:汇编以后的调用地址是相对于CALL的下一条指令的位移量。例:CALL0120
H;子程序偏移地址由指令给出(1)调用指令CALL5位移量由汇编程序在汇编时进行计算,如下例:CS:0102CALL0120H;3字节CS:0105……则位移量为:0120-0105H=001BH于是CALL0120H的机器码为E8
1B00CS:0102E8CS:01031BCALL0120HCS:010400CS:0105……6子程序的偏移地址在寄存器或存储器中。格式:CALLmem16/reg16CALL执行时,它首先将IP内容压栈,然后把指定的寄存器/存储器的内容送入I
P。例:CALLBX;子程序地址由BX给出CALLWORDPTR[SI];子程序地址在存储器中②段内间接调用7CALLIPHIPL代码段数据段CALLWORDPTR[SI]指令的操作图示:假定:(DS)=8000H,(SI)=1200H81200H81201H8子程序
的段地址和偏移地址直接由CALL指令给出。格式:CALLfar_proc;far_proc为远过程的地址指令的操作为:CS内容压栈IP内容压栈CS←段地址IP←偏移地址例:CALL2000H:1
000HCALLTIMER;TIMER为远过程③段间直接调用9子程序的段和偏移地址为存储器的连续4个单元中的内容。格式:CALLmem32指令的操作为:SP←(SP)-2((SP)+1,(SP))←(CS);CS压栈CS←(mem32+2)SP←(SP
)-2((SP)+1,(SP))←(IP);IP压栈IP←(mem32)例:CALLDWORDPTR[DI]调用地址在[DI],[DI]+1,[DI]+2,[DI]+3四个存储单元中。低字内容为偏移地址,高字内容为段地址。④段间间接调用10CALL代码段数据
段IPHIPLCSHCSL[DI][DI]+1[DI]+2[DI]+3段间间接调用示意图CALLDWORDPTR[DI]11段内返回指令RET的操作为:恢复子程序执行前IP的内容。段间返回指令RET的操作为:恢复子程序执行前IP和CS的内容。(2)返回指令RET124
.2.5宏定义伪指令如果需要多次使用同一个程序段,可以将这个程序段定义为一个”宏指令”,然后在需要时,可简单地用宏指令名来代替这个程序段。指令的格式为:<宏指令名>MACRO[形参表]<宏定义体>END
M13例:两个数之和的宏定义和宏调用。宏定义为:DADDMACROX,Y,ZMOVAX,XADDAX,YMOVZ,AXENDMX、Y、Z是形式参数。调用宏DADD时可写为:DADDDATA1,DATA2,SUMDATA1,DA
TA2,SUM是实际参数,由它们替换定义中的X、Y、Z。14宏调用与过程(子程序)调用都是一次定义,多次调用。它们之间的差别是:①执行形式:宏命令伪指令由宏汇编程序在汇编过理中进行处理,而CALL、RET则是由CPU执行的指令。②汇编结果:宏命令伪指令汇编后被展开。③执行速度:宏命令
执行速度较快(因无调用转移)④占用内存:宏指令简化了源程序,但不能简化目标程序,并不节省内存单元。使用过程可以节省代码占用的内存空间。15宏展开:汇编程序会把宏调用按宏定义展开。例如:宏定义为:DisplayMACROstringLEADX,stringMOVAH,9IN
T21HENDM程序中宏调用:……DISPLAYERROR_MESSAGEDISPLAYEXIT_MESSAGE……汇编后的结果:(带有+号的指令为宏展开后的结果)……+LEADX,ERROR_MESSAGE+MOVAH,9+INT21H+LEADX,EXIT_MESSAGE+M
OVAH,9+INT21H……164.2.6汇编结束伪指令END汇编语言源程序的最后,要加汇编结束伪指令END,以使汇编程序结束汇编。格式:END[表达式]END后跟的表达式通常就是程序第一条指令的标号,指示程序的启动地址(要执行的第一条指令
的地址)。174.3功能调用系统功能调用——由OS提供的一组实现特殊功能的子程序供程序员在程序中调用,以减轻编程工作量。系统功能调用有两种,一种称为DOS功能调用,另一种称为BIOS功能调用。用户程序在调用这些系统服
务程序时,不是用CALL命令,而是采用软中断指令INTn来实现。18INT2lH功能大致可以分为四个方面:设备管理、目录管理、文件管理和其它。D0S系统功能调用的使用方法如下:①AH←功能号;②设置该功能所要求的其他入口参数;③执行IN
TH指令;④分析出口参数。19INTN①当前标志寄存器的内容压栈,保存TF②TF←0,IF←0③当前断点的CS值压栈,当前IP④IP,CS←向量表中第N项的4–0~1FH,80H~F0H是ROMBIOS的中断向量号;–20H~3FH是DOS的中断向量号;–40H~7FH是用户备用
的中断向量号。20当中断服务子程序返回时,要执行IRET指①栈顶弹出一个字到IP②栈顶弹出一个字到CS③栈顶弹出一个字到标志寄存器211DOS功能调用(1)返回DOS向量号21H功能号4CHMOVAH,4CHINT21H(2)从键盘输入一个字符(功能号=1)MOVAH,1IN
T21H<AL中有键入的字符>22例:程序中有时需要用户对提示做出应答。GET_KEY:MOVAH,1;等待键入字符INT21H;结果在AL中CMPAL,’Y’;是’Y’?JZYES;是,转YESCMPAL,’N’;是’N’
?JZNO;是,转NOJMPGET_KEY;否则继续等待输入YES:……NO:…23(3)在显示器上显示一个字符(功能号=2)MOVAH,2MOVDL,<要显示的字符>INT21H例:在显示器上显示一个字符
‘A’MOVAH,2MOVDL,’A’;或MOVDL,41HINT21H24MOVAH,9LEADX,<字符串>INT21H注意:被显示的字符串必须以’$’结束。(4)显示字符串(功能号=9)25例:在屏幕上显
示:’HELLO,WORLD!’;在数据段定义字符串:DATASEGMENTSTR1DB‘HELLO,WORLD!$’DATAENDS;在代码段中进行显示输出MOVAH,9LEADX,STR1INT21H26例:在显示器上显示“HOWAREYOU?”,然后读一个字符,但不
显示此字符。若读入字符是“Y”,则显示“OK”。DSEGMENTD1DB`HOWAREYOU?`,0DH,0AH,`$`D2DB`OK`,0DH,0AH,`$`DENDSCSEGMENTASSUMECS:C,DS:D;说明代码段、数据段27BG:MOVAX,DMOVDS,AX;给
DS赋段值MOVDX,OFFSETD1MOVAH,9INT21H;显示“HOWAREYOU?”MOVAH,8INT21H;不显示方式读一字符到ALCMPAL,`Y`JNENEXT;不等则转LEADX,D2MOVAH,9INT21H
NEXT:MOVAH,4CHINT21HCENDSENDBG28(5)输入字符串(功能号=0AH)此功能调用从键盘输入一串字符并把它存入用户指定的缓冲区中。MOVAH,0AHLEADX,<字符串缓冲区首地址>INT21H(预
留的N1个字节的存储单元)0DHN2N1N1:缓冲区长度(最大键入字符数)N2:实际键入的字符数(不包括回车符)0DH:回车用户定义的输入字符串的缓冲区格式29若用户键入的字符数(包括回车)≥定义的N1,本功能调用将不再接收新的键入,且光标不再向右移动。例:设在数据段定义键盘缓冲区如下:STR
1DB10,?,10DUP(?)调用DOS功能的0AH号功能的程序段为:LEADX,STR1MOVAH,0AHINT21H此程序段最多从键盘接收10个按键(包括回车)。30例:屏幕显示“PASSWORD?”,随后从键盘读入字符串,并比较这个字符串与程序内部
设定的字符串。若二者相同则显示“OK”,否则不作任何显示(0DH是回车的ASCII码,0AH是换行的ASCII码)。31DSEGMENTPASS1DB`12AB`NEQU$-PASS1D1DB`PASSWORD?`,0DH,0AH,`$`PASS2DB20DB?DB20DUP(?)D2DB0DH,
0AH,`OK$`DENDSCSEGMENTASSUMECS:C,DS:D,ES:D;BG:MOVAX,DMOVDS,AX;给DS赋段值MOVES,AX;给ES赋段值32LEADX,D1;将D1表示的相对地址送DXMOVAH,9INT21H;显示“PASSWORD?”并回车换行LEAD
X,PASS2MOVAH,0AHINT21H;输入字符串LEASI,PASS1LEADI,PASS2CMPBYTEPTR[DI+1],NJNELASTMOVCX,NLEADI,PASS2+2CLDREPZCMPSB;重复比较J
ZDISOK33LAST:MOVAH,4CHINT21HDISOK:LEADX,D2MOVAH,9INT21H;显示“OK”JMPLASTCENDSENDBG342BIOS功能调用BIOS:基本输入输出系统,是固化在EPROM中的一
组实现基本输入输出功能的子程序。BIOS调用通过多个软中断提供,调用方法为:MOVAH,<功能号><设置入口参数,一般将参数放在寄存器中>INT<中断类型>BIOS中的几个主要中断类型如下:INT10H——屏幕显示INT13H——磁盘操作INT14H——串行口操作INT1
6H——键盘操作INT17H——打印机操作每类中断由包含许多子功能,调用时通过功能号指定。354.4汇编语言程序设计基础4.4.1概述1.程序质量(自学)2.汇编语言程序设计的步骤:1-根据实际问题抽象出数学模型,确定算法2-画出程序框图(流程图)3-分配内存工
作单元和寄存器4-根据框图编写源程序,存成.ASM文件5-对源程序汇编,生成.OBJ目标文件6-把.OBJ文件连接成.EXE执行文件7-运行、调试3.源程序的基本结构:顺序、分支、循环、过程36汇编语言上机过程YYYNNN有错?
有错?有错?结束汇编输入(修改)源程序连接运行查错开始用EDIT,NOTEPAD等任何文本编辑器。源程序存为.ASM文件用MASM宏汇编程序进行汇编。汇编后生成.OBJ目标文件。命令格式:MASM<源文件名.ASM>;用LINK连接程序进
行连接。连接后生成.EXE可执行文件。命令格式:LINK<目标文件名.OBJ>;用TD、DEBUG等调试程序进行调试。命令格式:TD<可执行文件名.EXE>374.58086/8088汇编语言程序设计基本方法4.5.1顺序结构程序4.5.2分支结构程序4.5.3循环结构程序4.5.4
DOS及BIOS中断调用返回384.5.1顺序结构程序例:对两个8字节无符号数求和,这两个数分别用变量D1及D2表示。将两数之和的最高位进位放在AL中,两数之和的其他位按从高到低顺序依次放在SI,BX,CX,DXDSEGMENTD1DB12H,34
H,56H,78H,9AH,0ABH,0BCH,0CDHD2DB0CDH,0BCH,0ABH,9AH,78H,56H,34H,12HDENDSCSEGMENTASSUMECS:C,DS:D;说明代码段、数据段39
BG:MOVAX,DMOVDS,AX;给DS赋段值LEADI,D1;将D1表示的偏移地址送DIMOVDX,[DI];取第1操作数到寄存器中MOVCX,[DI+2]MOVBX,[DI+4]MOVSI,[DI+6]LEADI,D2;将D2表示的偏移地址送DI40顺序结构程序(续1)ADDDX,
[DI]ADCCX,[DI+2]ADCBX,[DI+4]ADCSI,[DI+6]MOVAL,0ADCAL,0MOVAH,4CHINT21HCENDSENDBG41顺序结构程序(续2)例:试编写计算f=(
w-(x﹡y+z-5000))/x的程序。其中,w、x、y、z均为有符号16位二进制数,并假设w、x、y、z的值分别为5000、200、-250、20000。程序运行后,将计算结果存入变量F,而余数存入变量F+2中。分析:输入数据为w、x、y、z;输出数据为f。由f算式可知,它是
一个双字操作数除以字操作数所得的商,故f占一个字。由于中间结果x﹡y是双字操作数,所以,w、z均应将符号扩展成双字操作数之后再进行加减运算。计算的所有中间结果也都应按32位带符号二进制数处理。42现设定存储单元分配为
:字变量W、X、Y、Z分别存放w、x、y、z的值;字变量F、F+2中分别用来存放除法运算所得的商、余数。寄存器CX、BX用来存放运算的32位中间结果。则计算f值的步骤如下:43顺序结构程序(续4)①x﹡y→C
X、BX;②将z变量扩展成双字→DX、AX;③(CX、BX)+(DX、AX)→CX、BX;④(CX、BX)-5000→CX、BX;⑤将w扩展成双字→DX、AX⑥(DX、AX)-(CX、BX)→DX、AX⑦(DX、AX)/x,其商→F,余数→F+244计算程序如下:STAC
KSEGBENTACKDB200DUP(0)STACKEDNSDATASEGMENTWDW5000XDW200YDW-250ZDW20000FDW2DUP(?)45顺序结构程序(续5)DATAENDSCODESEGMENTASSUMECS:CODE,DS:
DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AX;为DS赋值MOVAX,XIMULY;x*y→DX,AXMOVCX,DXMOVBX,AX;x*y→CX,BX46MOVAX,ZCWD;将z扩展成双字→DX,AXADDBX,AXADCCX,DX;(CX,BX)+(DX
,AX)→(CX,BX),(x*y+z→CX,BX)SUBBX,5000SBBCX,0;(CX,BX)-5000→CX,BX,(x*y+z-500→CX,BX)MOVAX,WCWD;将w扩展成双字→DX,AXSUBAX,BXSBBDX,CX;(DX,AX)-(CX,BX)→DX,AX,
((w-(x*y+z-500))→DX,,AX)47顺序结构程序(续5)IDIVX;(w-(x*y+z-500))/x→AX,(w-(x*y+z-500))%x→DXMOVF,AXMOVF+2,DX;(DX,AX)/x,商→F,余数→F+2MOV
AH,4CHINT21H;退出用户程序,返回DOS状态CODEENDBEGIN程序运行后,在变量F中存入了200对应的十六进制数00C8H,而余数0送入变量F+2中。返回48程序结构:TEST/CMP指令Jx标号1处理体P1JMP标号2标号1:处理体
P2标号2:其他指令…条件满足?处理P1处理P2标号1:标号2:条件1条件24.5.2分支结构程序IF…THEN…ELSE结构49标号1:条件1成立?P1NYCASE结构程序结构:…TEST/CMP指令(测试条件1)Jx标号1;不满足转标号1处理体P1…JMP标号n+1标号1:
TEST/CMP指令(测试条件2)Jx标号2;不满足转标号2处理体P2…JMP标号n+1标号2:TEST/CMP指令(测试条件3)Jx标号3;不满足转标号3处理体P3…JMP标号n+1标号3:TEST/CMP
指令(测试条件4)……标号n+1:(公共出口)条件2成立?条件n成立?…Pn+1标号2:标号n:标号n+1:P2PnNNYY504.5.2分支结构程序例:比较以存储变量D1和D2表示的两个有符号字数据的大小,将其中较大数据放在BXDATASEGMENTD1DW-
123H;补码为FF85HD2DW-120H;补码为FF88HDATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA;说明代码段、数据段BEGIN:MOVAX,DATAMOVDS,AX;给DS赋段值
MOVBX,D1CMPBX,D2JGENEXT;若D1≥D2,则不交换,转NEXTMOVBX,D2;若D1<D251NEXT:MOVAH,4CHINT21HCODEENDSENDBEGIN524.5.2分支结构程序(续1)例:试编制计算下列函数值的程序(设x、y为带符号8位二进制数):1(
当x≥0,y≥0时)a=-1(当x<0,y<0时)0(当x、y异号时)DATASEGMENTXDB–12YDB9ADB?DATAENDS53STACKSEGMENTSTACKDB200DUP(0)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS
:STACKBEGIN:MOVAX,DATAMOVDS,AX;为DS赋值DATACMPX,0;判x是否为负JSL1;若x<0,则转L1CMPY,0;判y是否小于零JLL2;若x≥0、y<0,则转L2MOVA,1JMPEXIT;若x≥0,y≥0时,则1→A,无条件转EX
IT返回54L1:CMPY,0JGEL2;若x<0,y≥0时,则转L2MOVA,-1JMPEXIT;若x<0,y<0时,则-1→A且无条件转EXITL2:MOVA,0;若x与y异号时,则0→AEXIT:MOVAH,4CHINT21HCODEEN
DSENDBEGIN554.5.3例:找出从无符号字节数据存储变量VAR开始存放的N个数中的最大数放在BH中,程序如下:DSEGSEGMENTVARDB5,7,19H,23H,0A0HNEQU$-VARDSEGENDSCSEGSEGMENTASSUM
ECS:CSEG,DS:DSEG;说明代码段、数据段BG:MOVAX,DSEGMOVDS,AX;给DS赋段值MOVCX,N-1;置循环控制数MOVSI,0MOVBH,VAR[SI];取第1字节数到BHJCXZLAST;如果CX=0则转56循环结构程序(续1)AGIN:INCSICMPBH
,VAR[SI]JAENEXTMOVBH,VAR[SI]NEXT:LOOPAGIN;CX←CX-1,若CX不等于0则转LAST:MOVAH,4CHINT21HCSEGENDSENDBG57循环结构程序(续2)例:将一组有符号存储字节数据按从小
到大的顺序排序。设数组变量为VAR,数组元素个数为N设计思想是:反复对相邻的数作两两比较,并使相邻的两数按从小到大顺序排列,直到数组中任意两个相邻的数都是从小到大时,则排序结束。为简单起见,不仿设该组数是-1,8,-5,-8等4个数。VA
R〔1〕=-1VAR〔2〕=8VAR〔3〕=-5VAR〔4〕=-8第1轮比较:从第1个元素开始进行第1轮比较,需要作3次两两相邻的数据比较,且每对相邻的两数58比较后,保证前一个数据比后一个数据小。因此,3次比较并作交换后,这一组数中的最大数“8”就被排在最后,即:VAR〔1〕=-1VA
R〔2〕=-5VAR〔3〕=-8VAR〔4〕=859循环结构程序(续3)第2轮比较:经第1轮比较交换后,已经将最大数“沉入”最底,因此这一遍比较只需考虑前3个元素的排序,即进行2次比较。这一轮比较及交换后,数据的排列顺序为:VAR〔1〕=-5VAR〔2〕=-8VAR〔3〕=-
1VAR〔4〕=8第3轮比较:经第2轮比较交换后,最大的两个数已排好序,剩下只有两个较小数待排序,即比较1次,最后得到排序结果为:VAR〔1〕=-8VAR〔2〕=-5VAR〔3〕=-1VAR〔4〕=860经上
述分析后可知:对N个元素的排序采用这种算法思想最多要作N-1轮比较;第I轮比较时,应作N-I次两两比较及交换。61循环结构程序(续4)如果对第I轮的比较及交换用一子程序来实现,即子程序功能是从第1个元素开始作N-I次两两比较交换,主程序对该子程序作N-1次调用,即完成对N个数设子程序名为:
SUBP;子程序的输入为:DX表示当前是第几轮比较;数组为:VAR;子程序的输出为:作了第DXDSEGMENTVARDB-1,-10,-100,27H,0AH,47HNEQU$-VARDENDS62CSEGMENTASSUMECS:C,DS:D;说明代码段、
数据段B:MOVAX,DMOVDS,AX;给DS赋段值MOVCX,N-1;设置N-1轮比较次数MOVDX,1;比较轮次计数,输入子程序AG:CALLSUBPINCDXLOOPAGMOVAH,4CHINT21H63循环结构程序(续5)SUBPPROCPUSHCXMOVCX,NSUB
CX,DXMOVSI,0RECMP:MOVAL,VAR[SI];VARCMPAL,VAR[SI+1]JLENOCHXCHGAL,VAR[SI+1]]XCHGAL,VAR[SI]NOCH:INCSILOOPRECMPPOPCXRETSUBPENDPCENDSENDB返回64掌握以下几点:
调用子程序用CALL指令,返回调用程序用RET指令。子程序允许嵌套调用。进入子程序后首先要保护主程序的运行状态(标志位)和使用的寄存器内容(称为保护现场),退出子程序前要恢复现场。调用前要预先确定子程序中要使用哪些寄存器,并定义入口参数和出口参数。参数传递可利用寄存器、存储单元或
堆栈(要用BP寻址)。4.5.4子程序设计举例65例1:二进制数(0-F)转换成ASCII(‘0’-‘F’)的子程序。BIN2ASCPROC;要转换的数在AL的低四位;转换结果仍在AL中CMPAL,9JAA2FADDAL,30HJMPDONEA2F:ADDAL
,37HDONE:RETBIN2ASCENDP调用方法:(在主程序中)…MOVAL,0CHCALLBIN2ASC(AL中有0CH的ASCII码43H,’C’)