第6章-高级编程技术.ppt_第1页
第6章-高级编程技术.ppt_第2页
第6章-高级编程技术.ppt_第3页
第6章-高级编程技术.ppt_第4页
第6章-高级编程技术.ppt_第5页
已阅读5页,还剩145页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第 六 章,高级编程技术,6.1 移位指令及循环移位指令,6.2 串操作指令,6.3 宏指令,习 题 6,所谓高级编程技术,是指在汇编语言程序设计中,如果我们把移位及循环移位指令、串操作指令和宏指令巧妙地应用到汇编语言程序设计中,将大大提高编程质量和编程效率。 本章主要介绍这三类指令:移位及循环移位指令、串操作指令和宏指令的功能,并通过大量例子说明其应用。,6.1 移位指令及循环移位指令,移位指令完成对操作数的移位操作。分为一般移位和循环移位指令。移位操作也是将操作数倍增和减半的有效方法。,6.1.1 移位指令,(1)逻辑左移指令 【指令格式】 SHL D,COUNT D为通用寄存器或存储器操

2、作数。 COUNT表示移位的次数。 移位一次,COUNTR=1; 移位多次,COUNT=CL (CL中为移位的次数)。,【功能】对给定的目的操作数D(位16位)左移COUNT次。最高位移入CF中,最低位补零。 其操作示意图如图6-1所示。,图6-1 逻辑左移指令操作示意图,例如:如下逻辑左移指令: SHL AL,1 MOV CL,3 SHL CX,1 SHL DX,CL SHL ALFADI,1 SHL ALFADI,CL,说明:本指令影响标志位:OF、PF、SF,ZF。CF决定移入的最高位。,本指令主要用于向左移位操作。但因为左移一位相当于权值提高一级,故本指令又常作有、无符号数的倍增操作。

3、 但请注意,在左移一次后,当新的操作数最高位与CF不相同时,则OF置1,表明有符号数操作产生溢出,不再符合倍增关系。对无符号数,当移位后使CF置1,则不再符合倍增关系。,例如: AL=01000010B(66)/(+66) 左移一位后: AL=10000100(132)/ (124),CF=0,OF=1 上例表明,对无符号数,移位后CF=0,故移位前后数间符合倍增关系(66*2=132);而对有符号数,移位后OF=1发生了溢出,所以移位前后数间不再符合倍增关系(+66*2-124),【例6-1】编写程序段,把AX中的无符号数乘以8,如果有溢出,忽略超过16位的部分。 【分析】乘以8的操作可以通

4、过在二进制数的后面加3个0完成,即左移3位,移出部分自动丢失。只需要在CL中放移动位数(3位),再用SHL指令移位即可:,【解】指令序列如下: MOV CL,3 SHL AX,CL 对于双字型数据,或者位数更多的复杂数据,也可以用移位指令与逻辑运算指令配合,简化乘除法的运算。,逻辑右移指令 【指令格式】SHR D,COUNT D为任一通用寄存器或存储器操作数。 COUNT表示移位次数。 移位一次,COUNT=1; 移位多次,COUNT=CL (CL中为移位的次数)。,【功能】对给定的目的操作数D(8位/16位)右移COUNT次。最低位移入CF中,最高位补零。 其操作示意如图6-2所示。,图6-

5、2 逻辑右移指令操作示意图,例如:如下指令: SHR AL,1 MOV CL,3 SHR SI,CL SHR DX,CL SHR ALFADI,1 SHR ALFADI,CL,说明: 本指令影响标志位:OF、PF、SF,ZF。CF决定移入的最低位。 同样,本指令主要用于右向逻辑移位操作。但右移一位,相当权值下降一级。所以本指令可作为无符号数的除2运算。但请注意,在右移后,如果新的CF=1,表明移位前的数是一个奇数,则减半的结果是不精确的。,(3)算术左移指令 【指令格式】SAL D,COUNT D为任一通用寄存器或存储器操作数。 COUNT表示移位次数。 移位一次,COUNT=1; 移位多次,

6、COUNT=CL。 (CL中为移位的次数),【功能】对给定的目的操作数D(8位/16位)算术左移COUNT次。最高位移入CF中,最低位补零。 其操作示意图与图6.1完全相同。,说明:实际上SAL与SHL是同一指令的两种表示方法。具有完全相同的功能。它一般用来作为有符号数的倍增运算。 在左移一次后,如果新的CF与新的操作数最高位不相同,则标志OF=1。表明移位前、后的操作数不再具有倍增关系。,算术右移指令 【指令格式】SAR D,COUNT D为任一通用寄存器或存储器操作数。 COUNT表示移位次数。 移位一次,COUNT=1; 移位多次,COUNT=CL。 (CL中为移位的次数),【功能】对给

7、定的目的操作数D(8位/16位)右移COUNT次。最低位移入CF中,最高位保持不变。 其操作示意如图6-3所示。,图6-3 算术右移指令操作示意图,例如:(如下指令) SAR AL,1 MOV CL,6 SAR BX,CL SAR BX,1 SAR BETABX,1 SAR BETABX,CL,说明:本指令影响标志位:PF、SF,ZF。CF决定移入的最低位。同样,本指令常用于有符号数的减半运算。 但在右移使CF=1时,会产生减半运算结果不精确问题。,如:AL=11001110B(-50) 右移一位后: AL=11100111B(-25); CF=0,减半运算结果是精确的; 再右移一位后: AL

8、=11110011B(-13); CF=1,减半运算结果是不精确的,6.1.2 循环移位指令,循环移位指令是指对操作数进行首尾相连的移位操作。它共有4条指令。具有相似功能,一并说明如下:,【指令格式】 ROL D,COUNT ;左向循环移位 ROR D,COUNT ;右向循环移位 RCL D,COUNT ;带进位左向循环移位 RCR D,COUNT ;带进位右向循环移位,D为任一通用寄存器或存储器操作数。 COUNT表示移位次数。 移位一次,COUNT=1; 移位多次,COUNT=CL。 (CL中为移位的次数),【功能】对给定的目的操作数D(8位/16位)进行循环移位。 ROL/ROR实现左向

9、/右向不带CF的循环移位。 RCL/RCR实现左向/右向带有CF的循环移位。 它们的操作示意如图6-4所示。,图6-4 循环移位指令操作示意图,说明:本组指令只影响标志:CF、OF。CF决定于移入位。 OF决定于移位一次后符号位是否改变,如改变则OF=1,否则,OF=0。由于是循环移位,所以对字节只要移位8次(对字只要移位16位)就可以恢复为原操作数。 而带CF的循环移位,因CF参加循环移位,所以可以利用它实现多字节的循环移位。,【例6-2】在寄存器DX和AX中存放有32位二进制数(高位在DX中)。今要求实现乘4运算。 【分析】乘4运算可以通过对DX:AX左移二次,等价乘4的方法实现。先对低位

10、AX逻辑左移一次,然后再对高位DX循环左移一次,通过CF完成寄存器间的移位传递。通过二次同样的移位,就可实现乘4运算。,【解】指令序列如下: SHL AX,1 RCL DX,1 SHL AX,1 RCL DX,1 对于多个存储单元,也可以使用同样的方式完成移位操作。,【例6-3】编写程序段分别完成下列计算。 (1)把(DX,AX)构成的无符号双字除以4,商放在(DX,AX)中,余数放BX中。 (2)把(DX,BX)构成的无符号数乘以17,结果仍放在(DX,BX)中,忽略溢出。,【分析】在(1)小题中,由于没有直接的指令把双字型数据移位,所以通过CF作为过渡,连续做两次字型数据的移位,先把高字D

11、X右移1位,移出位暂时放在CF中,再用带进位CF的循环右移指令,在把低字移位的同时,把暂存在CF中的那1位移到低字的最高位上。,在(2)小题中,移动的位数较多,如果用循环的方式实现就违背了提高处理速度的本意。程序段中用AX取出低字部分的值,右移12位,把应该从低字移到高字的4位放在了AX的最低4位上。再把高字DX用SHL指令左移4位,移出部分自动丢失,右4位补0,最后把AX中存放的4位数据用OR指令(也可以用ADD指令)放到DX的低4位上,从而实现双字(DX,BX)乘以16的操作。,【解】(1)二进制无符号数除以4,就是把它向右移动两位,高位补0,原二进制数的最低两位就是余数。指令序列如下:,

12、MOV BX,AX AND BX,3 SHR DX,1 RCR AX,1 SHR DX,1 RCR AX,1,(2)17可以看作(16+1),因此可以把(DX,BX)先左移4位,结果记在(DX,BX)中,再与原数据相加。指令序列如下: MOV SI,BX MOV AX,BX MOV DI,DX MOV CL,4 SHL BX,CL SHL DX,CL,MOV CL, 12 SHR AX, CL OR DX, AX ADD BX, SI ADC DX, DI,6.2 串操作指令,汇编语言中的“串”是指内存中连续存放的若干个字节型或字型数据构成的一个整体,相当于一个数组。8086/8088为这种“

13、数组”的操作提供了专门的串操作指令,这些指令与循环或附加在串指令前的前缀配合,可以依次对串中的数据进行处理。,串操作指令都要求先把数组首元素(或者最后一个元素)的地址放在指定段寄存器和变址寄存器中,每处理一个数组元素,串指令本身自动把变址寄存器的内容做相应的变化,使其指向下一个待处理的元素。,根据实际需要,串操作指令可以按数组存放的内存地址从小到大进行处理,也可以从大到小处理,CPU在执行串指令时,会根据标志寄存器中的DF标志位选择处理的方向。,8086/8088有5条串操作指令,它们是串传送、串比较、串搜索、串装入和串送存。什么是元素?8086/8088做这样的约定:在字节串中,一个字节就是

14、一个元素;在字串中,一个字(两个字节)就是一个元素。,源串和目的串的存储及寻址方式都有隐含规定,即源串段地址在DS中,目的串段地址在ES中;SI存放源串的偏移地址,DI存放目的串的偏移地址;CX作为计数器。,6.2.1 DF标志位,DF是8086/8088中的一个重要的控制标志位,它决定了串指令的处理方向。当CPU执行到一条串操作指令时,如果DF的值是0,CPU会把指令相应的变址寄存器的值增加,按地址由小到大的方向处理;反之如果DF的值是1,CPU会把变址寄存器的值减小,按地址由大到小的方向处理。,8086/8088提供有两条专用指令设置DF,分别是CLD和STD指令。 【指令格式】CLD 【

15、功能】把标志位DF清0。,如果一开始SI或DI指向源串或目的串首地址,则DF应清0,以实现按增址方向对该串的处理。 如为字节串,每处理一个元素: SI+1SI,DI+1DI; 如为字串,每处理一个元素:SI+2SI,DI+2DI。以指向下一个元素。,【指令格式】STD 【功能】把标志位DF置1。 如果一开始SI或DI指向源串或目的串末地址,则DF应置1,以实现按减址方向对该串的处理。 如为字节串,每处理一个元素: SI1SI,DI1DI; 如为字串,每处理一个元素: SI2SI,DI2DI。以指向下一个元素。,6.2.2 与REP配合的串指令MOVS、STOS和LODS,1.串重复前缀 【指令

16、格式】 REP 串指令MOVS/STOS/LODS,【功能】 (1)判断CX的内容,如果CX=0,退出串操作,否则继续执行; (2)CX CX1; (3)执行其后的串指令; (4)重复(1)(3)。,图6-5 串重复前缀REP的功能,2串传送指令MOVS 【指令格式】 字节串传送 : MOVSB 字串传送 : MOVSW,【功能】 (1)执行MOVSB指令时,把数据段DS:SI所指内存单元的一个字节传送到附加段ES:DI所指字节单元,SI和DI自动加1或自动减1,即: ES:DI DS:SI, SI SI1, DI DI1,(2)执行MOVSW指令时,把数据段DS:SI所指内存单元的一个字传送

17、到附加段ES:DI所指字单元中。SI和DI自动加2或减2,即: ES:DI DS:SI, SI SI2, DI DI2,说明:执行串传送指令后,SI和DI是增值还是减值取决于状态标志DF。 DF=0,SI和DI自动增值; DF=1,SI和DI自动减值。,在串指令中,操作数隐含。因此在执行串指令前,应做以下准备工作: (1)DS:SI应指向源串首址或末地址,ES:DI应指向目的串首址或末地址。 (2)建立方向标志。若为增址型传送,用指令CLD,使方向标志DF清0;若为减址型传送,用指令STD,使方向标志DF置1。 (3)把数据串长度送入CX寄存器中。,【例6-4】将数据段BLOCK单元开始的10

18、0个字节依次传送到附加段BUF开始的内存区。 【解】程序如下: DATA SEGMENT BLOCK DB 10,30, ;定义100个数 DATA ENDS,EXTR SEGMENT BUF DB 100 DUP(?) EXTR ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA ASSUME ES:EXTR BEGIN: MOV AX,DATA MOV DS,AX MOV AX,EXTR MOV ES,AX,MOV SI,OFFSET BLOCK MOV DI,OFFSET BUF MOV CX,100 CLD REP MOVSB MOV AH,4CH INT

19、 21H CODE ENDS END BEGIN,【例6-5】设字节型变量str中存放了100个字符,编写程序段完成下列操作: (1)删除串中前5个字符,并把后续字符前移。 (2)把串中各字符向后移一个字节,在串首插入一个空格符。,【分析】第(1)题要把串的后95个字节向前移动,是源串首址大于目标串首址的情况,需要自首至尾进行移动;第(2)题正相反,源串首址小于目标串首址,只能按由尾至首的方向移动。,【解】程序如下: (1)MOV AX,SEG str MOV DS,AX MOV ES,AX LEA SI,str+5 LEA DI,str MOV CX,95 CLD REP MOVSB,(2)

20、 MOV AX,SEG str MOV DS,AX MOV ES,AX LEA SI,str+99 LEA DI,str+100 MOV CX,100 STD REP MOVSB MOV str, ,3串装入指令LODS 【指令格式】 字节串装入: LODSB 字串装入 : LODSW,【功能】 (1)执行LODSB指令时,把数据段DS:SI所指内存单元中的一个字节装入AL中,SI自动加1或减1,即: AL DS:SI, SI SI 1,(2)执行LODW指令时,把数据段DS:SI所指内存单元中的一个字装入AX中,SI自动加2或减2, 即: AX DS:SI, SI SI 2,说明:DF=0时

21、,SI自动增值;DF=1时,SI自动减值。该指令前一般不用重复前缀,其原因留给读者去思考。,【例6-6】设DS段中的变量arr中存放了一个带符号的字型数组,元素个数已放在字型变量arrlen中(0)。编写程序段,利用串操作指令,统计出该数组中正数、0和负数各多少个,结果分别放在DS段中的字型变量countp、count0和countn中。,【解】 MOV CX,arrlen MOV countp,0 MOV count0,0 MOV countn,0 LEA SI,arr CLD lab1: LODSW CMP AX,0,JG lab2 JL lab3 INC count0 JMP lab4

22、lab2: INC countp JMP lab4 lab3: INC countn lab4: LOOP lab1,4串送存指令STOS 【指令格式】 字节存储: STOSB 字存储: STOSW,【执行操作】 (1)执行STOSB指令时,把AL中的内容装入到附加段ES:DI所指内存单元中,DI自动加1或减1,即: ES:DI AL, DI DI1,(2)执行STOSW指令时,把AX中的内容装入到附加段ES:DI所指内存单元中,DI自动加2或减2,即: ES:DI AX, DI DI2 说明:DF=0时,DI自动增值;DF=1时,DI自动减值。,【例6-7】设DS段中的变量arr1中存放了一

23、个带符号的字型数组,元素个数已放在字型变量arr1len中(0)。编写程序段,试利用串操作指令,把该数组中非0元素复制到DS段中的另一个字型变量arr2中,要求在arr2中连续存放,并统计出非0元素的个数填在变量arr2len中。,【分析】首先把DS、SI、ES和DI指向正确的位置,然后利用循环指令,每次从arr1中取出一个数,若不是0,则存往arr2。由于是字型数据,循环结束后DI的值减去arr2的偏移地址可得到保存下来的数据占据了多少字节,除以2后即得元素个数。,【解】程序如下 PUSH DS POP ES LEA SI, arr1 LEA DI, arr2 MOV CX, arr1len

24、 CLD lab1;LODSW,TEST AX,AX JZ lab2 STOSW Lab2: LOOP lab1 SUB DI, OFFSET arr2 SHR DI, 1 MOV arr2len, DI,6.2.3 与REPE和REPNE配合的串指令CMPS和SCAS,REPE和REPZ等价,当相等或为零重复串操作; REPNE和REPNZ等价,当不相等或不为零重复串操作。,1REPE/REPZ 【指令格式】 REPE(或REPZ) 串指令CMPS/SCAS 【功能】 (1)CX = 0或ZF = 0,退出串操作,否则继续执行; (2)CX CX 1; (3)执行其后的串指令; (4)重复(

25、1)(3),图6-6 串重复前缀REPE/REPZ的功能,2.REPNE/REPNZ 【指令格式】 REPNE(或REPNZ) 串指令CMPS/SCAS 【功能】 (1)CX = 0或ZF = 1,退出串操作,否则继续执行; (2)CX CX 1; (3)执行其后的串指令; (4)重复(1)(3),图6-7 串重复前缀REPNE/REPNZ的功能,3串比较指令CMPS 【指令格式】 字节串比较 : CMPSB 字串比较: CMPSW,【功能】 (1)执行CMPSB指令时,用数据段DS:SI所指内存单元中的一个字节与附加段ES:DI所指单元中的一个字节相减,根据结果设置状态标志,SI和DI自动加

26、1或减1,即:DS:SI ES:DI, SI SI 1, DI DI 1,(2)执行CMPSW指令时,用数据段DS:SI所指内存单元中的一个字与附加段ES:DI所指单元中的一个字相减,根据结果设置状态标志,SI和DI自动加2或减2,即: DS:SI ES:DI, SI SI 2, DI DI 2 说明:DF=0时,SI,DI自动增值;DF=1时,SI,DI自动减值。,【例6-8】编写子程序,按字典排序法,比较两个已知长度的字符串的大小。 【解】程序如下:,;子程序名:strcmp ;子程序功能:按字典排序法比较两个已知长度的字符串的大小 ;入口参数:DS:SI和ES:DI分别存放第1个串和第2

27、个串的起始逻辑地址, ;CX和DX分别放两个串的串长 ;出口参数:AL为1表示第1个串大,AL为-1表示第2个串大,AL为0表示两者相等 ;破坏寄存器:AH,CX,SI,DI,strcmp PROC NEAR CLD MOV AH, 0 CMP CX, DX JB lab1 MOV AH, 1 JE lab MOV CX, DX,MOV AH, 2 lab1:JCXZ lab2 CMPSB JA lab3 JB lab4 LOOP lab1 lab2:CMP AH,1 JB lab4,JA lab3 MOV AL,0 JMP lab5 lab3:MOV AL,1 JMP lab5 lab4:M

28、OV AL,-1 lab5:RET strcmp ENDP,4串搜索指令SCAS 【指令格式】 字节串搜索: SCASB 字串搜索: SCASW,【功能】 (1)执行SCASB指令时,用AL中的内容作为关键字与附加段ES:DI所指存储单元中的一个字节相减,根据结果设置状态标志ZF,DI自动加1或减1,即 : AL ES:DI, DI DI 1,(2)执行SCASW指令时,用AX中的内容作为关键字与附加段ES:DI所指存储单元中的一个字相减,根据结果设置状态标志ZF,DI自动加2或减2,即: AX ES:DI, DI DI 2 说明:DF=0时,DI自动增值;DF=1时,DI自动减值。,【例6-

29、9】编写一个子程序,判断一个数据串中是否存在一个给定的值。要求子程序对字节型和字型的串都能判断,以CF作为出口参数,如果在串中找到目标值,在CF位置1,否则令CF清0。 【解】程序如下: ;子程序名:search ;子程序功能:判断一个数据串中是否存在一个给定的值(字节串或字串),;入口参数:ES:DI数据串的首地址 ;AX查找目标值,字节串则以AL存放目标值 ;CX串中元素个数 ;CF0表示串中元素是字型,1则表示串中元素是字节型 ;出口参数:CF1表示在串中找到了给定值,0表示没找到 ;破坏的寄存器:CX,DI,search PROC NEAR JCXZ s2 CLD JC s3 REPN

30、Z SCASW JZ s1 JMP s2,s3: REPNZ SCASB JZ s1 s2: CLC JMP s4 s1: STC s4: RET search ENDP,6.2.4 串操作指令的应用,在应用程序设计中,经常会遇到各种字符或字符串的处理。在系统软件中,对大量字符串的操作则更加频繁。因此,字符串的处理是计算机应用的一个重要方面。,【案例6-1】设计一个口令设置程序。其功能如下: 程序执行首先显示提示: Please input the password:(请输入口令:) 如果用户输入正确的口令: USER(并回车),则输出: OK!WELCOME YOU,否则显示提示: Erro

31、r! Input again:(有错误,请重新输入:) 三次口令输入不对,就退出。 【案例分析】口令设置,实际上就是两个字符串进行比较看它们是否相等。,【案例求解】 源程序清单如下: ;filename:E6_1.ASM DATA SEGMENT PASSWORD DB USER,0DH COUNT EQU $PASSWORD INPUT DB COUNT DB ?,STRING DB COUNT DUP(?) PROMPT DB Please input the DB password: $ MSG1 DB 0DH,0AH,OK!WELCOME DB YOU,0DH,0AH,$ MSG2 D

32、B 0DH,0AH, Error! Input DB again: $ DATA ENDS,CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX, DATA MOV DS,AX MOV ES,AX MOV DX,OFFSET PROMPT MOV AH,09H INT 21H MOV BX,3 AGAIN: LEA DX,INPUT,MOV AH,0AH INT 21H LEA SI, PASSWORD LEA DI, STRING MOV CX,COUNT CLD REPE CMPSB JZ EXIT CALL CRLF,LEA DX,,MSG2

33、 MOV AH,,9 INT 21H DEC BX JNZ AGAIN JMP DONE EXIT: CALL CRLF LEA DX,MSG1 MOV AH,09H,INT 21H DONE: MOV AH, 4CH INT 21H ;_ CRLF PROC MOV AH, 02H MOV DL, 0DH INT 21H,MOV DL,0AH INT 21H RET CRLF ENDP ;_ CODE ENDS END START,6.3 宏指令,在编写汇编语言程序时候要用到一组基本上相似的汇编语言语句,它们完成相同的功能,有时候这组语句完全相同,有时候仅是有些变量略有差异,为了减轻编写程序

34、的负担,可以使用汇编语言中的宏。,宏就是源程序中一段有独立功能的程序代码,它只需要在源程序中定义一次,就可以多次调用,调用时只需使用一个宏指令语句就可以了。,6.3.1 宏的定义、调用和展开,宏的定义是由一组伪指令实现的。其格式是: 宏名 MACRO形参表 ;宏体 ENDM,其中,MACRO和ENDM是一对伪指令,分别表示宏定义的开始和结束。宏名必须唯一,在其后面的源程序中,可通过宏名来调用宏。形参表由若干个形式参数组成,当调用宏时,要用对应的实际参数去取代,向宏中传递信息。 宏的定义可以是汇编语言所允许的任意语句(指令或伪指令)序列,它决定了宏的功能。夹在MACRO和ENDM之间的语句序列,

35、我们把它们称作宏体。,宏经过定义以后,就可以在源程序中调用,这种调用称为宏调用。宏名可以像指令一样被使用,故又称为宏指令。 宏调用的格式如下: 宏名实参表,实参表也就是上边所说的实际参数,它和形参表相对应,用于取代宏定义中的形式参数。一般情况下,实参个数和形参个数相同,如果实参多于形参,则多余的实参被忽略;反之,实参少于形参,形参将被赋为空值。 当源程序被汇编时,汇编程序将用宏体取代相应的宏指令,并用实参取代形参,下面举例说明宏的定义、调用和展开。,【例6-10】定义一个宏,将前两个字操作数相加,结果放到第三个操作数中。 宏定义:,ADD_M MACRO OPRD1,OPRD2,RESULT

36、PUSH AX MOV AX,OPRD1 ADD AX,OPRD2 MOV RESULT,AX POP AX ENDM,宏指令(宏调用): ADD_M BX,CX,DX ADD_M OP1,OP2,OP3 宏展开以后应该是:, PUSH AX MOV AX,BX ADD AX,CX MOV DX,AX POP AX , PUSH AX MOV AX,OP1 ADD AX,OP2 MOV OP3,AX POP AX ,在宏定义中,如果需要用到寄存器,应该先将寄存器入栈,以免影响程序的执行,第一个调用的三个实参分别是三个寄存器;第二个调用的三个实参分别是已经定义的变量。,6.3.2 宏定义中的参数

37、,宏定义中的参数可以为多种形式,下面,我们通过例子来说明。 【例6-11】宏定义可以没有参数,下面宏定义用于从键盘读入一个字符放在AL中。,宏定义: INPUT MACRO MOV AH,1 INT 21H ENDM 宏指令(宏调用): INPUT,宏展开: MOV AH,1 INT 21H,【例6-12】参数可能是操作数或操作码。 宏定义: OPT_VAR MACRO OP1,OP2 PUSH AX MOV AX,OP1 OP2 AX MOV OP1,AX POP AX ENDM,宏指令(宏调用): OPT_VAR VAR1,DEC 宏展开: PUSH AX MOV AX,VAR1 DEC

38、AX MOV VAR1,AX POP AX 通过宏调用,完成了对变量VAR1的减1操作。,【例6-13】使用&作分隔符,参数是操作数或操作码的一部分。 宏定义: CONJMP MACRO DIRE,REG,COUNT SH&DIRE A®,COUNT ENDM 宏调用: CONJMP L,X,1 CONJMP R,L,CL,宏展开: SHL AX,1 SHR AL,CL 这个宏可以实现寄存器AX的左移或AL的右移。,6.3.3 宏与子程序的比较,(1)处理的时间不同。宏调用是在源程序被汇编时由汇编程序处理的;而子程序调用是在程序执行期间由CPU直接执行的。,(2)处理的方式不同。宏必须先

39、定义后调用,宏调用是用宏体替换宏调用伪指令,实参代替形参,源程序被翻译成目标代码后宏定义随之消失;而子程序的调用没有这样的替换操作,是以CALL指令将控制权由调用者转给子程序,(3)目标代码的长度不同。由于每一次宏调用都要进行宏展开,把宏体中的内容复制一遍,因而用宏编写的程序在目标代码中会重复出现相同或相似的程序段,占用内存空间大;而子程序是由CALL指令调用,无论调用多少次,子程序的目标代码只在最终的执行程序中出现一次,目标代码相对较短。,(4)执行速度不同。子程序调用时会比宏展开后的代码多执行CALL指令和RET指令,以及需要附加的指令进行参数传递,因而执行速度稍慢。,(5)参数处理不同。

40、宏调用是以实参代替形参,参数的形式不受限制,可以是指令助记符、寄存器名、标号等;而子程序的参数传递必须有确切的存放地。,编写程序的过程中,对于程序中的重复部分,究竟是采用宏还是子程序,程序员可以权衡内存空间、执行速度、参数传递方法等各方面的因素后取舍。在大多数情况下,宏比子程序有更大的灵活性,且执行速度快,在重复部分较短时经常采用;,而一个已经验证过的子程序,可以做成目标代码存放在子程序库中,在另一个程序中应用时可不经过汇编程序的翻译,直接与需要使用它的程序连接在一起,从而避免宏展开后可能出现的语法及逻辑错误。,6.3.4 宏在编程中的应用,【例6-14】设计一个程序,键入字符串到BUFER缓冲区,然后用程序判别,如为小写字符则转换成大写字符输出。要求键盘字符串输入、回车换行和屏幕单字符输出采用宏调用实现。,【

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论