1 / 19

5.3 宏指令语句

5.3 宏指令语句. 1. 宏指令、宏定义和宏调用 宏指令是源程序中具有独立功能的一段程序代码。在汇编语言中,如果在源程序中需要多次使用同一个程序段,可以将这个程序段定义(宏定义)为一个宏指令,然后每次需要是,即可简单地用宏指令名来代替(称为宏调用),从而避免了重复书写,使源程序更加简洁、易读。 宏定义由 MASM 宏汇编程序提供的伪指令实现,其格式为. …. 宏体. 宏指令名 MACRO [形式参数] ENDM 宏调用的格式为 宏指令名 [实际参数] 这就是说,只要在源程序中写上已定义过的宏指令名就算是调用该宏指令了。

dakota
Download Presentation

5.3 宏指令语句

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 5.3 宏指令语句 1.宏指令、宏定义和宏调用 宏指令是源程序中具有独立功能的一段程序代码。在汇编语言中,如果在源程序中需要多次使用同一个程序段,可以将这个程序段定义(宏定义)为一个宏指令,然后每次需要是,即可简单地用宏指令名来代替(称为宏调用),从而避免了重复书写,使源程序更加简洁、易读。 宏定义由MASM宏汇编程序提供的伪指令实现,其格式为

  2. 宏体 宏指令名 MACRO [形式参数] ENDM 宏调用的格式为 宏指令名 [实际参数] 这就是说,只要在源程序中写上已定义过的宏指令名就算是调用该宏指令了。 具有宏调用的源程序被汇编时,每个宏调用将被MASM进行宏展开。宏展开实际上是用宏定义式设计的宏体去代替相应的宏指令,并用实际参数一一取代形参。

  3. 由此可见,使用宏的过程共有三步:首先进行宏定义;然后可以进行宏调用;最后,汇编时由MASM进行宏展开。由此可见,使用宏的过程共有三步:首先进行宏定义;然后可以进行宏调用;最后,汇编时由MASM进行宏展开。 [例] 若源程序中多处需要将AL和CL寄存器中的两位压缩型的BCD数相加,并将和送回BL寄存器,则可象下述这样定义宏指令,然后在需要的地方进行调用。 DECADD MACRO ADD AL,CL DAA ENDM 显而易见,这是一个无形式参数的宏定义。

  4. 如果对分别存放在任意8位寄存器或存储单元中的两个压缩型的BCD数进行加法运算,则可将上例宏定义改写为如果对分别存放在任意8位寄存器或存储单元中的两个压缩型的BCD数进行加法运算,则可将上例宏定义改写为 DECADD1 MACRO OPR1,OPR2 MOV AL,OPR1 ADD AL,OPR2 DAA MOV OPR1,AL ENDM 这是一个带有两个形式参数的宏定义。宏指令为DECADD1。例如有以下宏调用:

  5. DECADD1 DL, BUFFER DECADD1 AREA1, AREA2 则汇编时进行宏展开,得到以下指令: DECADD1 DL, BUFFER + MOV AL, DL + ADD AL, BUFFER + DAA + MOV DL, AL DECADD1 AREA1, AREA2 + MOV AL, AREA1 + ADD AL, AREA2 + DAA + MOV AREA1, AL 宏扩展后,原来宏体中的指令前面都加上了符号“+”,以示区别。

  6. 声明宏体内局部标号的伪指令(LOCAL) LOCAL的作用是声明宏体中的局部标号,以免在宏扩展时,同一个标号在源程序中多次出现,从而产生标号多重定义的错误。LOCAL伪指令必须位于宏体内其它所有语句(包括注释)之前,其格式为: LOCAL 局部标号[,…] 例如下面的宏指令完成将寄存器中的一位十六进制数转换为相应的ASCII码,由于宏体中出现局部标号,因此必须使用LOCAL伪指令对宏体中的局部标号进行声明。 HEXTOASC MACRO REG LOCAL NUM CMP REG,0AH JC NUM ADD REG,07H NUM: ADD REG,30H ENDM

  7. 宏指令与子程序的区别 在汇编语言程序设计中,宏指令和子程序都给设计者提供了很大方便。他们都是可被程序多次调用的程序段,并且调用前必须由设计者袭击根据需要按一定格式进行定义。然而,宏指令和子程序由于定义方法和几个是不同,使用中患有许多不同之处,主要是空间和时间的差异。 ⑴ 子程序由CALL指令调用,由RET指令返回,所以汇编后子程序的机器码只占有一个程序段,不管调用多少次均如此,较为节约内存。宏指令在每次宏调用处宏展开时,宏体都要占一个程序段,调用次数愈多,占用内存愈多。因此从内存空间开销来说,子程序优于宏指令。

  8. 从程序的执行时间来分析,每调用一次子程序都要保护和恢复返回地址(断点)及寄存器内容(现场)等,要消耗较多的时间。宏指令调用时不需要这个过程,执行时间较短。因此,从执行时间来分析,宏指令又优于子程序。 综上所述,当某一需多次访问的程序段较长,访问次数又不是太多时,选用子程序结构较好。当某一需多次访问的程序段较段,访问次数又很频繁时,选用宏指令结构显然要更好些。

  9. DELY TIMER1,TIMER2 MOV DL,30H MOV AH,02H INT 21H DELY TIMER2,TIMER1 MOV DL,36H INT 21H MOV AH,4cH ;返回dos INT 21H CODE ENDS END start ;宏调用举例,通过修改TIMER1和TIMER2实现不同的延时 TIMER1 EQU 0100H TIMER2 EQU 1000H CODE SEGMENT ASSUME CS:CODE start: ;宏定义开始 DELY MACRO DATA1,DATA2 LOCAL LOOP1,LOOP2 PUSH CX PUSH AX MOV CX,DATA1 LOOP1: MOV AX,DATA2 LOOP2: DEC AX JNZ LOOP2 LOOP LOOP1 POP AX POP CX ENDM ;宏定义结束 Macro.asm

  10. 5.4 常用系统功能调用和BIOS功能调用 DOS及BIOS功能调用属于软件中断,即可用INT n指令调用的中断,它可分为三部分: ⑴ DOS 中断,占用中断类型号为20H~27H和2FH,其余类型号保留。 ⑵ ROM BIOS 中断,占用中断类型号10H ~1FH。 ⑶ 自由中断,占用中断类型号40H ~FFH,可供系统或应用程序设置开发的中断处理程序用。

  11. 1、DOS中断及功能调用 DOS常用的9类中断(20H~27H和2FH)可分为两种: ⑴ DOS专用中断。DOS专用中断是指INT 22H、 INT 23H、 INT 24H 3个中断,属DOS操作时专用,用户不要直接使用。 ⑵ DOS可调用中断。DOS可调用中断是指INT 20H、 INT 21H、 INT 25H、 INT 26H、 INT 27H和INT 2FH 6个中断。这6个中断都供用户直接调用,但都必须要满足一定的入口条件。其中:

  12. ① 磁盘读写中断。INT 25H、INT 26H分别用来读和写磁盘上的若干扇区,这实际上是两条BIOS调用。 ② 程序退出中断。INT 20H、INT 27H都为程序的退出命令。 ③ 假脱机打印文件中断。INT 2FH用来实现假脱机打印文件命令PRINT。 ④ 系统功能调用。又称为DOS功能调用,是指 INT 21H 中断。它是可供系统程序和应用程序调用的一个极其重要的中断,内含近百个子功能。

  13. 2、系统功能调用 1.系统功能调用方法 DOS启动成功后,INT 21H 的中断向量(中断处理程序的首地址)被初始化在中断向量表中,向量地址为84H87H的4个存储单元内。调用 INT 21H的方法如下: ⑴ 入口参数送相应的寄存器; ⑵ 子功能编号送AH; ⑶ 发出中断请求:INT 21H 2.常用系统调用子功能

  14. ⑴ 01H号调用(带回显的键符输入) 1 号子功能是从标准输入设备输入一个字符,并送入寄存器AL,不许入口参数。例如: MOV AH, 01H INT 21H 执行上述指令,系统将扫描键盘,等待有键按下,一旦有键按下,就将键值(相应字符的ASCII码值)读入,并送入AL寄存器,同时将这个字符显示在屏幕上。

  15. ⑵ 0AH号调用(字符串输入) 从键盘接收字符串到内存输入缓冲区,要求事先定义一个输入缓冲区,缓冲群诶第一个字节指出缓冲区的字符个数,不能为零。第二个字节保留已用作填写输入的字符实际个数。从第三个字节开始存放从键盘上接收的字符。调用时,要求DS:DX指向输入缓冲区的首地址。键入字符串以回车结束。 例如,从键盘输入一个小于50个字符的字符串数据。其程序设计方法是:

  16. DATA SEGMENT BUF DB 50 DB ? DB 50 DUP(?) DATA ENDS CODE SEGMENT … MOV DX, OFFSET BUF MOV AH, 10 INT 21H … CODE ENDS

  17. ⑶ 02H号调用(字符输出显示) 2号功能是将一个字符(一个ASCII码值)输出到标准输出设备(即显示器或打印机)。入口参数为DL寄存器,寄存器DL中存放待输出的字符。例如: MOV DL, ‘A’ MOV AH, 2 INT 21H 即将字符“A”显示在屏幕上或输出到打印机。

  18. ⑷ 09H号调用(字符串输出) 9号功能调用是将缓冲区中的一组以“$”结束的字符串送标准输出设备输出(显示器或打印机)。调用前必须将输出缓冲区的首地址送DS:DX。例如: DATA SEGMENT BUF DB ‘HOW DO YOU DO ? $’ DATA ENDS CODE SEGMENT … MOV DX, OFFSET BUF MOV AH, 9 INT 21H … CODE ENDS

  19. 3、BIOS中断调用 在IBM-PC机的ROM存储器中包含一些基本输入输出子程序。这些基本输入输出子程序简称为BIOS。它们的功能与DOS中字符I/O功能相似,用户也可通过软件中断方式直接调用。由于BIOS提供的字符I/O功能直接依赖于硬件,因而调用它们比调用DOS字符I/O功能速度更快。例如: ☆键盘输入子程序。调用指令为 INT 16H ☆屏幕显示子程序。调用指令为 INT 10H ☆打印输出子程序。调用指令为 INT 17H

More Related