汇编语言——宏

合集下载

宏汇编汇编语言

宏汇编汇编语言
宏的参数形式灵活多变,可以是常数、变量、存储单元、指 令操作码或它们的一部分,也可以是表达式,使用灵活多变 的参数,同一个宏定义甚至可以执行不同的操作。
几个宏操作符的使用
%:表达式操作符:将其后面跟的表达式的值作为实参, 而不是将表达式本身作为参数,用在实参中。 &:替换操作符:用于将参数与其他字符分开。用在 宏体中。如果参数紧跟在其他字符之前或之后, 或者 参数出现在带引号的字符串中,就必须使用该伪操作 符。
宏汇编应用举例 例5-17 P148
multiply macro opr1,opr2,result
push dx push ax
; 定义宏
code segment assume
ds:data,cs:code,ss:stack start: mov ax,data
mov al,opr1 imul opr2 mov result,ax
在什么情况下使用宏?为什么要使用宏?
在汇编语言程序设计过程中,可以将具有一 定功能,需多次重复使用,且比较短的程序 段定义成一条宏指令。
使用宏指令语句可以减少程序书写错误,缩 短源程序长度,使源程序编写像高级语言一 样清晰、简洁。特别是使用宏库后,可以提 高编程效率。
比较

子程序
➢ 仅是源程序级的简化: 宏调用在汇编时进行 程序语句的展开,不 需要返回;不减小目 标程序,执行速度没 有改变
5.6 宏结构程序设计
什么是宏?
宏是源程序中一段有独立功能的程序代码。 它只需在源程序中定义一次就可以多次调用它, 调用时,只需要用一个宏指令语句就可以了
宏(Macro)是汇编语言的一个特点,它是 与子程序类似又独具特色的另一种简化源程序的 方法
宏汇编
宏结构 重复汇编

8086汇编语言宏指令语句

8086汇编语言宏指令语句

Source listing[NUL.LST]: (源列表文件名)
列表文件名(缺省:无列 表文件)
Cross reference[NUL.CRF]: 交叉参考文件用的文件名 (缺省:无交叉参考文件) (交叉参考文件名)
第5章 汇编语言程序设计
5.2.3 用连接程序生成可执行程序文件(EXE 文件) 经汇编后产生的目标程序文件(OBJ文件)并不 是可执行程序文件,必须经连接后才能成为可执行文件 (EXE文件)。连接程序并不是专门为汇编语言程序设 计的,如果一个程序是由若干个模块组成的,也可以通 过连接程序把它们连接在一起。这些模块可以是汇编程 序产生的目标程序文件,也可以是高级语言编译程序产 生的目标程序文件。 完成连接功能的程序是LINK程序。连接过程如下 表所示:
第5章 汇编语言程序设计
⑵ 从程序的执行时间来分析,每调用一次子程序 都要保护和恢复返回地址(断点)及寄存器内容(现场) 等,要消耗较多的时间。宏指令调用时不需要这个过程, 执行时间较短。因此,从执行时间来分析,宏指令又优 于子程序。 综上所述,当某一需多次访问的程序段较长,访 问次数又不是太多时,选用子程序结构较好。当某一需 多次访问的程序段较短,访问次数又很频繁时,选用宏 指令结构显然要更好些。
库文件名表(各文件之间 用+号隔开)
第5章 汇编语言程序设计
DATA SEGMENT … DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA, ES:DATA START: MOV AX, DATA MOV DS, AX MOV ES, AX … MOV AH, 4CH INT 21H CODE ENDS END START
第5章 汇编语言程序设计
5.5.1 用编辑程序建立汇编语言源程序文件

汇编第7章 宏汇编

汇编第7章 宏汇编

占用内存空间大

macro2
macroN
>EDIT EXP.ASM 调用宏库:
include MACRO.MAC …… macro1 [实元表] …… macro2 [实元表] …… macroN [实元表] ……
删除不用 的宏定义
purge macroN
汇编语言程序设计 汇编语言程序设计
子程序调用与宏调用工作方式的区别
宏定义: msg
errmsg
cntr=0 宏调用: …… errmsg …… errmsg 1 1 宏展开: 2 1 1 2 cntr msg msg1 …… cntr msg msg2
‘SYNTAX ERROR’
‘INVALID OPERAND’
= cntr+1 %cntr,‘SYNTAX ERROR’ db ‘SYNTAX ERROR’ = cntr+1 %cntr,‘INVALID OPERAND’ db ‘INVALID OPERAND’
指令:程序运行时执行的语句 汇编语言源程序 伪指令(伪操作):汇编时执行 宏指令:汇编时展开
汇编语言程序设计 汇编语言程序设计
一、 宏定义、宏调用和宏展开
宏定义: macro_name MACRO [哑元表] ; 形参/虚参 …… …… ; 宏定义体 ENDM
宏调用: (必须先定义后调用) macro_name [实元表] 宏展开: 宏定义体
汇编语言程序设计 汇编语言程序设计
三、宏汇编操作符: &
符号1 & 符号2
;;
%
宏展开时 , 合并前后两个符号形成一个符号。 & 可 以作为哑元的前缀。 ;; 注释 宏展开时,;; 后面的注释不予展开。 % 表达式

汇编语言——第3章宏汇编语言

汇编语言——第3章宏汇编语言

第三章宏汇编语言一:宏汇编语言格式3.1.1 指令语句格式指令语句的一般格式如下:[标号:]指令助记符操作数;注释1.标号:标号是机械指令语句寄存地址的符号表示,代表该指令目标代码的第一个字节地址,后面必需紧跟冒号“:” 。

2.指令助记符:指令助记符为语句的核心成份,表示了该语句的操作类型。

3.操作数:操作数表示指令助记符的操作对象。

4.注释:注释均以分号开始,它可占一行或多行,一般放在一条语句的后面。

3.1.2 伪指令语句格式伪指令语句格式如下:[符号名] 伪指令符操作数;注释1.符号名:符号名是伪指令语句的一个可选项。

2.伪指令符:伪指令符指定汇编程序要完成的具体操作,如数据概念伪指令DB、DW、DD,段概念伪指令SEGMENT,假定伪指令ASSUME等。

2.操作数:伪指令后面的操作数能够是常数、字符串、变量、表达式等,其个数由具体的伪指令决定,各个操作数之间必需以“逗号”分隔。

4.注释:伪指令的注释必需以“;”开始,其作用同指令语句中的注释部份。

汇编语句表达式3.2.1 常量1.数值常量2. 字符串常量字符串常量是用单引号或双引号引发来的一个或多个字符。

字符串常量是以各字符的ASCⅡ码表示的。

如‘A’用41H 表示,字符串‘A1B2’用41H,31H,42H,32H表示。

3.2.2 变量1.变量(1)段属性(2)偏移地址属性(3)类型属性2.变量的概念表达式项是给变量或指定存储单元给予初值,它有以下几种形式:(1)数值表达式数据概念伪指令能够为一个或持续的存储单元设置数值初值。

【例】为数据段分派存储单元。

DATA SEGMENTA DB 11H,12H,13HB DW 1122H,3344HC DD HDATA ENDS上述变量的存储单元分派及初始化情形如下图所示。

数据段中数据存储分派图(2)字符串表达式字符串表达式中的字符串必需用引号引发来。

DB、DW、DD伪指令将字符串中的各字符均以ASCⅡ码形式寄存在相应的存储单元,但表示形式各不相同。

第4章 宏汇编语言

第4章 宏汇编语言

(4)分析运算符 分析运算符有SEG、 OFFSET、TYPE、LENGTH和 SIZE。分析运算符可以把一个存储单元的地址分解为 相应的段地址和偏移量。 ①SEG运算符
格式:SEG段名
功能:计算某个逻辑段的段基址。
②OFFSET运算符
格式:OFFSET变量名或标号名
功能:算出变量名(或标号名)的地址偏移量。
2.变量、变量定义伪指令
1)变量和标号 变量代表内存操作数的存储地址,或者说变量名 就代表某个存储单元。标号代表指令地址,它为 转移指令提供了转移目标。由于标号和变量是用 一串字符命名的,从这个意义上讲,标号和变量 又称为符号地址。标号和变量的命名规则是:以 字母或者下划线开头,后跟字母、数字、下划线, 长度不超过31个字符,并且系统中保留字不能作 为标号和变量名。保留字是系统中已经专用的有 特殊意义的名字,例如,指令的操作码助记符、 运算符、寄存器名称、伪指令助记符等等。
标号被定义在代码段,变量通常被定义在数据 段、附加段或堆栈段。 标号和变量都有共同的3个属性。即: a.段属性。即标号或变量所在段的段基址,用 SEG运算符可以计算得到。 b.偏移属性。即标号或变量所代表的存储单元, 相对于段首址之间的地址偏移量(又称有效地 址),用OFFSET运算符可以计算得到。
⑤ SIZE运算符 格式:SIZE 变量名
功能:计算一个存储区域所占用的字节数。
(5)综合运算符
ASM中,综合运算符有PTR和THIS。
THIS综合运算符的功能是改变存储区的类型,THIS 运算符也被称为类型指定运算符。THIS运算符的运 算对象是数据类型(BYTE、WORD、DWORD)或 者距离类型(NEAR、FAR),用于规定所指变量或 者标号类型属性或者距离属性。

汇编语言——宏

汇编语言——宏

【例7.14】形式参数还可以出现在变量定义伪操作的初值表 中,甚至是以字符串形式出现的初值。 msg MACRO num,pname 'HELLO, &pname'
var&num DB ENDM
汇编语言规定,字符串中的形参必须用分隔符“&”从其它 部分分离出来。对于下面两个宏调用, msg msg 1,John 2,Henrry
code
ENDS END main
【解】宏展开后的结果是: + + + + + + MOV MOV INT MOV MOV INT MOV INT AH,2 DL, '*' 21H AH,2 DL, '*' 21H AH,4CH 21H
由于宏展开是汇编程序翻译的一个步骤,宏展后的结果 并不是源程序,所以展开后不再写出完整的程序格式,只列 出有效指令部分。 可以看到,汇编程序对宏调用与已定义的常量及符号的 引用的处理是很类似的,定义部分在汇编处理结束后就已完 成它的作用。汇编程序翻译后得到的机器代码中没有宏、常 量等的定义,只是调用或引用部分被代换成宏体或定义的内 容。宏与常量定义及符号定义的差别在于,常量及符号定义 都必须在一行写完,对常量和符号的引用只能代换指令中的 操作数,或者操作数的一部分,宏调用则可以代换一段程序。 不仅如此,宏还允许代换的内容有个别地方不同,这是通过 带参数的宏实现的。
(3)宏定义仅仅用来告诉汇编程序,将来宏调用时复制 的对象是什么,宏定义中的程序段并不是程序的一部分,也 就是说,如果程序中定义了一个宏而没有调用它,汇编程序 将忽略宏定义。 (4)宏定义可以写在程序的任何地方,但习惯上总是把 宏定义写在程序的最前面。 宏定义与编辑器中的文字块的定义有相似之处,也有一 些差别。两者都需要以特定的方式说明开始和结束的位置。 文字块是文件的一部分,而宏体中的程序段必须经过宏调用 才能复制到源程序中正确的位置,没有被调用的宏体在汇编 程序翻译时会被忽略。

04宏汇编语言

04宏汇编语言

• 例如: • MOV DS:[BX],12H ;错误 • 因为无法指明操作数的长度类型。
• PTR临时修改变量名的属性 • 类似地,任何一条指令也必须明确变量名或 标号的类型。 • 变量名具有默认的类型属性。例如,使用 DB ABC定义:变量名ABC为字节类型,那么: • MOV DS:[ABC],12H ;正确
字节定义伪指令
• • • • • • • • 格式:[变量名] DB 一串用逗号间隔的单字节数 例如: BUF1 DB 55,66H,7*7 DB ?,? COUNT1 EQU $ - BUF1 ;COUNT1为? BUF2 DB 10 DUP(12H, 2 DUP (12, 34)) COUNT2 EQU $ - BUF2 ;COUNT2为? ①DB是Define Byte的缩写,DB伪指令的功能是通 知汇编程序,把所定义的单字节数转换成二进制数, 并从指定的变量单元开始依次存放。用DB伪指令定 义的这些单元的属性为“字节型”。

• •

• PTR指定存储器操作数长度 明确变量的长度类型十分重要。汇编语言规 定:任何一条指令必须明确内存操作数的长 度类型! 使用PTR指定存储器操作数长度的情况: 1、在单操作数指令中,该操作数为存储器操 作数(非变量名)时; 2、双操作数指令:当源操作数为立即数,目 的操作数为存储器操作数(非变量名)时;
• PTR临时修改标号或子程序名的类型属性 • 关于标号或子程序名的类型属性:由于各种 符号名不允许重名,编译程序能够自动识别 标号的类型属性。 • 程序中根据需要,仍然可以使用PTR临时修 改段内/段间的属性。
• 理解:对于一个NEAR型的标号ABC,仍然 可以使用如下指令: • JMP FAR PTR ABC ; (已验证!)

汇编语言——宏

汇编语言——宏

因此,对这一类错误提示,程序员只能自己按规则进行宏展 开,并判断展开后的结果是如何出的错。对于MASM汇编程 序比较熟悉的人,还可以借助于MASM处理源程序时产生的 一个.LST文件(只要在MASM提问“Source listing[NUL.LST]” 时输入一个合适的文件名即可产生清单文件),判断程序中 的错误,以及查看宏展开的结果。 另外,宏调用的优先级高于其它伪指令和指令,所以如 果用伪指令或指令助记符等内部保留字作为宏的名字,则汇 编程序会把这样的标识符当作宏进行处理,而使得源程序中 无法使用其原有的功能。汇编语言中还提供了一个PURGE伪 指令,用于在源程序适当的位置取消某个宏。比如:
code
Байду номын сангаас
ENDS END main
【解】宏展开后的结果是: + + + + + + MOV MOV INT MOV MOV INT MOV INT AH,2 DL, '*' 21H AH,2 DL, '*' 21H AH,4CH 21H
由于宏展开是汇编程序翻译的一个步骤,宏展后的结果 并不是源程序,所以展开后不再写出完整的程序格式,只列 出有效指令部分。 可以看到,汇编程序对宏调用与已定义的常量及符号的 引用的处理是很类似的,定义部分在汇编处理结束后就已完 成它的作用。汇编程序翻译后得到的机器代码中没有宏、常 量等的定义,只是调用或引用部分被代换成宏体或定义的内 容。宏与常量定义及符号定义的差别在于,常量及符号定义 都必须在一行写完,对常量和符号的引用只能代换指令中的 操作数,或者操作数的一部分,宏调用则可以代换一段程序。 不仅如此,宏还允许代换的内容有个别地方不同,这是通过 带参数的宏实现的。
【例7.16】设有如下宏定义: sum MACRO a,b LOCAL next MOV CX,a LEA BX,b XOR AX,AX next:ADD AX,[BX] ADD ENDM 并已知buf1和buf2是已定义的两个变量,展开下面的宏调用: sum 5,buf1 sum 7,buf2 BX,2 LOOP next

宏汇编

宏汇编

宏汇编摘要: 宏(Macro )是具有宏名的一段汇编语句序列(宏定义时书写),是汇编语言的一个特点,它是与子程序类似又独具特色的另一种简化源程序的方法宏指令——这段汇编语句序列的缩写(宏调用时书写)宏展开——宏指令处用...宏(Macro )是具有宏名的一段汇编语句序列(宏定义时书写),是汇编语言的一个特点,它是与子程序类似又独具特色的另一种简化源程序的方法宏指令——这段汇编语句序列的缩写(宏调用时书写)宏展开——宏指令处用这段宏代替的过程(宏汇编时实现)宏的参数功能强大,颇具特色配合宏,还有宏操作符和有关伪指令宏(Macro )是源程序中一段有独立功能的程序代码。

它只需在源程序中定义一次,就可以多次调用它,调用时只需用一个宏指令语句就可以了。

宏定义是用一组伪操作来实现的.其格式是:宏名macro [ 形参表]…宏定义体endm其中macro 和endm 是一对伪操作,这对伪操作之间是宏定义体(一组有独立功能的程序代码).宏名给该宏定义的名称,调用时就使用宏名来调用该宏定义,宏指令名给出该宏定义的名字,调用时就是用宏指令名来调用宏定义。

例如:宏名的第一个符号必须是字母,其后可以跟字母、数字和下划线字符。

MAINBEGING MACRO ;; 定义名为MAINBEGIN 的宏,无参数MOV AX,@DATA ;; 宏定义体MOV DS,AXENDM ;; 宏定义结束MAINEND MACRO RETNUM ;; 带有形参RETNUMMOV AL,RETNUM ;; 宏定义中使用参数MOV AH,4CHINT 21HENDMMULTIPLY MACRO OPR1,OPR2,RESULT;; 定义名具有三个参数的宏PUSH DX ;; 宏定义体PUSH AXMOV AX,OPR1IMUL OPR2MOV RESULT,AXPOP AXPOP DXENDM ;; 宏定义结束宏名[ 实参表]宏调用经宏定义定义后的宏指令可以在源程序中调用,这种对宏指令的调用称为宏调用。

第03章 汇编语言程序设计5_宏汇编

第03章 汇编语言程序设计5_宏汇编


子程序
宏与子程序具有各自的特点, 宏与子程序具有各自的特点,程序员应该根据具 体问题选择使用那种方法 通常,当程序段较短或要求较快执行时, 通常,当程序段较短或要求较快执行时,应选用 当程序段较长或为减小目标代码时, 宏;当程序段较长或为减小目标代码时,要选用子 程序
宏的实例2 宏的实例2
dispmsg
macro message mov ah,9 lea dx,message int 21h endm … dispmsg string … mov ah,9 lea dx,string int 21h
;;宏定义 宏定义 ;;宏定义体 宏定义体
;宏调用(宏指令) 宏调用(宏指令) 宏调用 ;宏展开 宏展开
宏与子程序的比较 比较

仅是源程序级的简化 : 仅是源程序级的 简化: 宏 简化 在汇编时进行程序语 调用在汇编时 调用 在汇编时 进行程序语 句的展开, 不需要返回; 句的展开 , 不需要返回 ; 不减小目标程序, 不减小目标程序 , 执行速 度没有改变 通过形参、 通过形参 、 实参结合实现 参数传递, 简捷直观、 参数传递 , 简捷直观 、 灵 活多变
子程序
还是目标程序级的简化 : 还是目标程序级的 简化: 简化 子程序调用在执行时由 CALL指令转向 RET指令返 指令转向、 CALL指令转向、RET指令返 形成的目标代码较短, 回 ; 形成的目标代码较短 , 执行速度减慢 需要利用寄存器、 需要子程序的比较结论 比较 结论
1. 宏定义
宏定义由一对宏汇编伪指令 宏定义 由一对宏汇编伪指令MACRO和 ENDM来 和 来 由一对宏汇编伪指令 完成,格式如下: 完成,格式如下: 形参表] 宏名 MACRO [形参表 形参表 …… ;宏定义体 ENDM 其中宏名是符合语法的标识符, 其中宏名是符合语法的标识符 , 同一源程序中该 名字定义唯一。宏定义体中不仅可以是硬指令序 名字定义唯一 。 宏定义体 中不仅可以是硬指令序 列,还可以是伪指令语句序列 可选的形参表给出了宏定义中用到的形式参数, 可选的形参表给出了宏定义中用到的形式参数 , 每个形式参数之间用逗号分隔

汇编语言09

汇编语言09
dispmsg MACRO message mov dx,offset message mov ah,09h int 21h ENDM
MACRO ;;定义名为mainbegin的宏,无参数 mov ax,data1 ;;宏定义体 宏注释符 mov ds,ax ENDM ;;宏定义结束 MACRO retnum mov al,retnum mov ah,4ch int 21h ENDM ;;带有形参retnum ;;宏定义中使用参数
第9章
9.2.3 宏中的标号处理
1. 2.
把标号定义为形式参数 在宏定义中声明标号为局部标号 局部标号伪指令格式
LOCAL LAB1[,LAB2,…]
功能
LOCAL的作用就是要告诉汇编程序宏体中这些标号是局部的。
说明
LAB1,LAB2,…是宏体中出现的标号。它必须是宏定义 MACRO语句之后的第一条语句,即MACRO和LOCAL之间不能 有任何字符行。 汇编程序在宏扩展时,将对宏体中的局部标号产生唯一的标号。
MAC1 MACRO … MAC2 MACRO … MAC3 MACRO …EN源自M… ENDM … ENDM
当宏定义中嵌套 宏定义时,必须首先 调用最外层宏定义, 然后才能调用内层宏 定义。下面是一个宏 嵌套的例子。
例9.6 用嵌套的形式定义将AL中的数据转换为两个十六进制数的ASCII码的宏指令。 有如下宏调用: BHTOA1 MACRO MOV AH, AL AHHN MACRO LOACAL AHHN1 MOV CL, 4 SHR AH,CL CMP AH,10 JC AHHN1 ADD AH,7 AHHN1: ADD AH,30H ENDM ALLN MACRO LOCAL ALLN1 AND AL,0FH CMP AL,10 JC ALLN1 ADD AL,7 ALLN1: ADD AL,30H ENDM ENDM BHTOA1 AHHN ALLN 1 AHHN

汇编语言 第七章 宏定义

汇编语言 第七章 宏定义

;; 有参数
endif
int 21h
ENDM
msg1 dstring msg2 dstring
start:
.model small
例题
.stack 256
.data
equ this byte
<Hello,Everybody !!>
equ this byte
<You see,I made it.>
.code
mainbegin @data
;建立DS内容
dispmsg msg1
;显示msg1字符串
dispmsg msg2
;显示msg2字符串
mainend
;返回DOS
end start
• 宏定义删除伪指令 PURGE 宏名表 不需要某个宏定义时,可以把它删除
• 宏定义退出伪指令 EXITM 伪指令EXITM表示结束当前宏调用的展开
第七章第一高章级汇基编础语知言识技术
第七章第一高章级汇基编础语知言识技术
第七章第一高章级汇基编础语知言识技术
第七章第一高章级汇基编础语知言识技术
第七章第一高章级汇基编础语知言识技术
宏结构程序设计
宏汇编 重复汇编 条件汇编 ——统称宏结构 宏(Macro)是汇编语言的一个
特点,它是与子程序类似又独具特色 的另一种简化源程序的方法
宏汇编
宏——具有宏名的一段汇编语句序列 ——宏定义时书写
宏指令——这段汇编语句序列的缩写 ——宏调用时书写
宏展开——宏指令处用这段宏代替的过程 ——宏汇编时实现
宏定义:
第七章第一高章级汇基编础语知言识技术
例 宏定义可允许递归调用,此时条件伪操作可用来结束宏递归。

汇编语言宏指令语句

汇编语言宏指令语句
示。
参数传递
在宏调用时,将参数值传递给宏的参 数占位符,以便在宏体中使用这些值。
可选参数
可选参数是指在宏定义中未指定的参 数,可以在宏调用时选择是否传递。
参数替换
在宏体中,可以使用参数占位符来表 示参数,并在宏调用时将参数值替换 到相应的占位符位置。
03
汇编语言宏指令语句的分类
数据宏指令语句
总结词:定义数据
可视化
可视化编程工具的发展将为汇编 语言宏指令语句提供更好的支持, 使编程更加直观和方便。
THANKS
感谢观看
宏调用
宏调用
在程序中,使用宏名称和参数列表来调用宏 。
参数替换
在宏体中,可以使用参数占位符来表示参数,并在 宏调用时将参数值替换到相应的占位符位置。
宏展开
在程序预处理阶段,将宏定义的指令语句展 开到程序中相应的位置,以实现代码复用。
宏参数
位置参数
位置参数是指在宏定义中按照顺序指定 的参数,可以在宏体中使用占位符来表

02
汇编语言宏指令语句基础
宏定义
01
02
03
04
宏定义
在汇编语言中,宏是一 种预处理指令,用于定 义一个或多个宏指令语 句,以便在程序中重复 使用。
宏名称
宏的名称是自定义的标 识符,用于在程序中引 用宏。
宏参数
宏可以接受参数,以便 在宏调用时传递值。
宏体
宏体包含宏定义的指令 语句,这些语句将在宏 调用时被替换。
操作数宏引用
在指令中使用操作数宏,例如:`MOV AX, @REG`。
控制流宏指令语句实例
无条件跳转宏
使用`JMP`指令,可以定义无条件跳转宏, 例如:`JMP label`。

宏汇编 汇编语言第5章

宏汇编 汇编语言第5章

需要利用寄存器、存 储单元或堆栈等传递 参数

比较 结论
子程序
相同点:简化源程序的设计和结构 不同点: ※ 对目标程序的长度影响不同。 ※ 对目标程序执行速度的影响不同。 ※ 传递参数的方式不同;传递参数过程中如出现错误,错误 的性质不同。(宏:语法;子程序:逻辑) 宏与子程序具有各自的特点,程序员应该根据具体问题选择 使用那种方法 通常,当程序段较短或要求较快执行时,应选用宏;当程序 段较长或为减小目标代码时,要选用子程序
例如:对上面的宏定义的调用形式为:

FILLSEG DATA ; DATA为数据段的段名
┆ 说明:(1)汇编时,汇编程序对每个宏调用作宏展开 ––– 用宏 定义体取代源程序中的宏指令名,用实参代替宏定义中的形参。 取代时,实参和形参是一一对应的。 若实参个数>形参个数,则 多余实参不考虑 , 若实参个数 <形参个数,则多余形参作“空” 处理。 (2)取代后,所得到的语句应该是有效的,否则汇编程序将会指 示出错。 (3)每调用一次就把宏定义体展开一次,因而它占有的存储空间 与调用次数有关。
比较

仅是源程序级的简化: 宏调用在汇编时进行 程序语句的展开,不 需要返回;不减小目 标程序,执行速度没 有改变
子程序
还是目标程序级的简 化:子程序调用在执 行时由CALL指令转向、 RET指令返回;形成的 目标代码较短,执行 速度减慢
通过形参、实参结合 实现参数传递,简捷 直观、灵活多变
表达符操作%示例。 DA MACRO A, B, C, D DW A, B, C DB D DUP(0) 则相应的宏展开为: 1 DW 12, 5, 30 1 DB 15 DUP(0) 1 DW X+2, 5, X+Y 1 DB Y-5 DUP (0)

汇编语言-宏指令

汇编语言-宏指令

3. 伪指令IRPC 伪指令IRPC与伪指令IRP相似,但实参数列是一个字符串。 一般格式如下: IRPC 形式参数 , 字符串 需重复的语句组 ENDM 字符串的长度规定了重复的次数。 如果字符串含有空格、逗号等分隔符,那么字符串需用一对尖 括号括起来。 例: IRPC X , 0123 DB X ENDM 展开后是得到: DB 0 , 1 , 2, 3 还是:换!
尽管都实现了调用,但是宏调用和子程序的调用是有差别的:
宏调用更多地是表示一种替换!
(二)宏指令的用途 1. 缩短源代码 2. 扩充指令集 3. 更改某些指令助记符的意义 (宏指令的优先级高于指令和伪指令) (三)宏指令中参数的使用 宏指令可以不带参数,但往往带有参数的宏指令更具灵活性。 1. 指令的参数可以是常数、寄存器和存储单元,还可以是表达 式。 例: MOV CL , 4 SAL AL , CL 如上述代码要多次使用,就可以定义为: SHIFT MACRO MOV CL , 4 SAL AL , CL ENDM
2. 伪指令IRP 伪指令IRP用于创建重复块,重复次数及每次使用的实参由实 参数列决定。 一般格式如下: IRP 形式参数, <实参1 ,实参2 ,……, 实参n> 需重复的语句组 ENDM 实参的个数规定了重复的次数。 例:下面的重复块实现把0-9的平方值存入存储区中。 IRP X , <0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9> DB X * X ENDM 再如:下面重复块吧若干寄存器值压入堆栈。 IRP REG , <AX , BX , CX , DX> PUSH REG ENDM
5. 与宏有关的伪指令 (1)局部标号说明伪指令 LOCAL 格式:LOCAL 标号表 标号表由标号构成,标号间用逗号分隔。 汇编程序在每次展开时,总把由LOCAL伪指令说明的标号用 唯一的符号(??0000至??FFFF)代替,从而避免标号重 定义错误。 例如:定义一个取绝对值的宏 ABSOL MACRO OPER LOCAL NEXT CMP OPER , 0 JGE NEXT NEG OPER NEXT: ENDM

汇编宏

汇编宏

这篇文章是我花了一个晚上作的总结,从一个比较本质的角度解释了一些宏的行为,不是教科书设置是Programmer Guide达到的程度。

看起来比较没有味道,但是如果你要用起宏来你会发现我几乎没有说废话。

不是教你怎么去用宏,但是你看过之后也不用学了,自己试验一下就可以写了。

虽然没有几个家伙还在用MASM,更少人用MACRO了,可能这个就是我另类的风格吧。

MASM宏使用总结导语MASM(Macro Assembler)是由微软公司提供的汇编工具,虽然有些年头了,但是仍然存在于 这样比较新的工具中。

有很多汇编教科书以这个为对象,讲述了如何用汇编去设计一个程序,作为计算机科学系学生的基础课。

但是,讲述的内容大体上还是停留在5.1版,而且停留在DOS的时代。

虽然提到了win32下的汇编,但是并没有放在首要的位置。

另一个被忽视的是作为MASM最大特色的宏,怎么去看待汇编工具中提供的强大的宏,以及怎么和在什么场合下使用宏,语焉不详。

本文是作者在大量使用MASM宏,搭建了一个汇编环境下的OOP 系统后,作的一个总结。

善用宏,能够减少重复编码,以及构建强大的功能,是重用代码,美化代码的一个有力的工具。

宏在高级语言中是一个应该被极力避免的东西,在低级语言中确未必如此。

宏就是预处理宏就是在代码被汇编成为obj文件之前进行的预处理。

由于发生在汇编期(Assembly-Time, 和高级语言中的编译期是一个意思),所以不会给执行期带来负担,可以用作代码生成工具,设置和C++中的模板一样,用作meta-programming 的工具。

在MASM中宏可以分为两种:1、 Text Macro 2、Procedure (Function) Macro。

第一种宏就是和#define pi 31415926这样的简单的文本替换的宏,第二种就是那种带参数,可以有局部变量,可以返回值这样的可以看作函数或者过程的宏。

下面就先从Text Macro入手,看看如何使用简单的宏。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【例7.14】形式参数还可以出现在变量定义伪操作的初值表 中,甚至是以字符串形式出现的初值。
msg MACRO num,pname
var&num DB
ENDM
'HELLO, &pname'
汇编语言规定,字符串中的形参必须用分隔符“&”从其它 部分分离出来。对于下面两个宏调用, msg msg 1,John 2,Henrry
在前面标以加号“+”以示区别。
【例7.10】参照汇编程序的处理方法,对下面程序中的宏进
行展开。 back = 4CH 21H
dosint EQU dispch MACRO MOV MOV INT ENDM
AH,2 DL, '* ' 21H
code
SEGMENT ASSUME CS:code
main:
是有限制的,所以源程序中在不同位置调用这样的宏,那些
离标号定义处较近的可以不超过范围因而没有语法错误,但 那些离标号定义处远的就不保证了。
【格式】LOCAL 标号1, 标号2, … 【功能】用于告诉汇编程序,在宏展开时,对宏体中出
现的“标号1”、“标号2”等标号定义,代换为特殊的各不相
同的标号。汇编程序在遇到用LOCAL说明的标号时,会代 以??0000、??0001、?0002、……等特殊的标识符,以保证宏
体中的标号定义在每次宏展开时各不相同,避免重复定义的
情况。
【例7.16】设有如下宏定义:
sum MACRO a,b LOCAL next
MOV CX,a
LEA BX,b XOR AX,AX
next:ADD AX,[BX]
ADD BX,2 LOOP next
ENDM
并已知 buf1 和 buf2 是已定义的两个变量,展开下面的宏调用: sum 5,buf1 sum 7,buf2
MOV AX,x
MUL AX
ENDM
mm2 MACRO a,b,c mm1 a
MOV BX,AX
mm1 b
ADD AX,BX MOV c,AX ENDM

mm2 v1,v2,v3
【解】展开mm2后得到: + mm1 v1 + MOV BX,AX + mm1 v2 + ADD AX,BX + MOV v3,AX 其中还含有宏调用,再把两个mm1展开后可得到如下结果: + MOV AX,v1 + MUL AX + MOV BX,AX + MOV AX,v2 + MUL AX + ADD AX,BX + MOV v3,AX
(3)宏定义仅仅用来告诉汇编程序,将来宏调用时复制
的对象是什么,宏定义中的程序段并不是程序的一部分,也 就是说,如果程序中定义了一个宏而没有调用它,汇编程序 将忽略宏定义。 (4)宏定义可以写在程序的任何地方,但习惯上总是把
宏定义写在程序的最前面。
宏定义与编辑器中的文字块的定义有相似之处,也有一 些差别。两者都需要以特定的方式说明开始和结束的位置。 文字块是文件的一部分,而宏体中的程序段必须经过宏调用 才能复制到源程序中正确的位置,没有被调用的宏体在汇编 程序翻译时会被忽略。
编程序会把这样的标识符当作宏进行处理,而使得源程序中
无法使用其原有的功能。汇编语言中还提供了一个PURGE伪 指令,用于在源程序适当的位置取消某个宏。比如:
add MACRO x,y
ENDM ADD AX,BX

PURGE add ADD AX,BX
这样的源程序中,前一个ADD被当作宏调用处理(汇编 语言是不分大小写的),进行宏展开;后一个ADD由于已用 PURGE伪指令取消了作为宏的add宏调用,使得该标识符恢 复原功能,因此是ADD指令。
可以看到,两次调用宏 sum ,展开后的结果中标号分别 是??0000和??0001,是不同的。如果宏定义中没有LOCAL伪 操作,展开结果中将在两个地方定义标号 next,是重复定义。 汇编语言还规定,LOCAL伪操作必须出现在宏体的第1 行上,在“宏名 MACRO”与LOCAL伪操作之间不允许有任
现为指令助记符)含有形式参数,符号“&”用于把形参cmd 从标识符中分离出来。如果没有分隔符号“&”,汇编程序将 把Jcmd作为一个整体处理,而不知道其中的cmd是形参。 对例7.12后面的3个调用,调用例7.13中的宏可以达到同
样的效果,相应写法是:
cc1 cc1 cc1 G,n1 BE,n2 NZ,n3
宏展开的结果是: + var1 DB 'HELLO, John'
+ var2
DB
'HELLO, Henrry'
*7.3.4 宏操作中形参与实参的对应关系
由于宏是伪操作,形参与实参的对应方法是由汇编程序 决定的,与高级语言中形参与实参的对应方式有很大的不同。
汇编语言规定:
(1)形参表中的多个参数项之间必须用逗号分隔,但实 参表的各个参数项可以用逗号也可以用空格分隔。 (2)如果形参的数目与实参的数目相等,则按照形参表 与实参表中各参数项的次序一一对应。
(3)如果形参数目少于实参数目,多余的实参被忽略,
汇编程序不做任何提示。
(4)如果形参数目多于实参数目,不足的实参作空串处 理,汇编程序也不做提示。 (5)如果实参中包含逗号、空格等分隔符作有效符号, 必须用尖括号“< >”括起来,避免混淆。
【例7.15】设有宏定义如下:
data MACRO p,q v&p DB q
由于宏展开是汇编程序翻译的一个步骤,宏展后的结果
并不是源程序,所以展开后不再写出完整的程序格式,只列 出有效指令部分。
可以看到,汇编程序对宏调用与已定义的常量及符号的
引用的处理是很类似的,定义部分在汇编处理结束后就已完 成它的作用。汇编程序翻译后得到的机器代码中没有宏、常 量等的定义,只是调用或引用部分被代换成宏体或定义的内 容。宏与常量定义及符号定义的差别在于,常量及符号定义
cc
JG,n1
JBE,n2
cc
JNZ,n3
【例7.13】宏的形式参数可以作为一个标识符的一部分。这 时,必须用符号“&”把形式参数与标识符的其余部分分开。 例7.12中的宏定义还可以写成下面的形式: cc1 MACRO CMP J&cmd ENDM cmd,lab AX,BX lab
宏体中第2行的J&cmd就是在一个标识符中(例7.13中表
ENDM
以及下面的宏调用: x x data + v1 = = %x,%x DB 1 1 x+1 data %x,%x
其宏展开结果是:
+ v2
DB
2
பைடு நூலகம்
符号“%”的作用体现在宏展开中是用常量标识符x的值
(第1次宏调用时是1,第2次宏调用时是2),而不是符号x本 身,去替换宏展开时的形参。 需要注意的是,宏操作与源程序的其它部分一样,都要 经过汇编程序的处理。汇编程序在处理带有宏调用的程序时,
7.3.5 宏体中的标号
宏体中出现标号分为两种情况:一是在带有跳转功能的
指令中,标号作为跳转的目的地,也就是对标号的引用;另
一种是宏体中某条指令的前面出现标号,即标号定义。如果 宏体中引用标号,由于汇编语言允许从程序的不同地方用跳
转指令跳转到同一位置,所以即使源程序中对这样的宏多次
调用,展开后的结果并不违反语法规则。但是需要注意,如 果标号的引用出现在条件跳转指令中,由于条件跳转的距离
【例7.11】普通用法,形式参数出现在操作数的位置。
dch MACRO MOV AH,2 x
MOV
INT ENDM
DL,x
21H
源程序中调用宏dch时,应该在宏名字的后面跟一个实际 参数,从例7.11的宏体可以看出,这个实际参数应该是用于屏 幕显示的一个ASCII字符。因而,源程序中用下面的写法连续 两次调用上述宏,就可以实现回车换行操作。宏展开时,对每 一次宏调用,将分别以相应的实际参数代换宏体中的形式参数。
因此,对这一类错误提示,程序员只能自己按规则进行宏展 开,并判断展开后的结果是如何出的错。对于MASM汇编程 序比较熟悉的人,还可以借助于MASM处理源程序时产生的 一个.LST文件(只要在MASM提问“Source listing[NUL.LST]” 时输入一个合适的文件名即可产生清单文件),判断程序中 的错误,以及查看宏展开的结果。 另外,宏调用的优先级高于其它伪指令和指令,所以如 果用伪指令或指令助记符等内部保留字作为宏的名字,则汇
是先进行宏展开,再进行语法检查及翻译。宏体在定义时,
由于可以带有一些形式参数,在没有进行代换之前很可能是 不符合语法规则的,但宏调用并展开后是否符合语法规则,
需要由汇编程序来判定。如果展开后的指令或伪指令有错,
汇编程序只能指出宏调用有错,并指出宏调用所在行的号码, 却无法指出究竟是展开后的哪一行不符合语法。
7.3.7 宏与子程序的比较
(1)处理的时间不同。宏调用是在源程序被汇编时由汇
编程序处理的;而子程序调用是在程序执行期间由 CPU直接
执行的。 (2)处理的方式不同。宏必须先定义后调用,宏调用是 用宏体替换宏调用伪指令,实参代替形参,源程序被翻译成 目标代码后宏定义随之消失;而子程序的调用没有这样的替 换操作,是以CALL指令将控制权由调用者转给子程序
7.3.2 宏调用 定义后的宏名又称为宏指令。经宏定义后,就可以在 源程序中调用宏了。宏调用的方式是在源程序中需要复制
宏体的地方写宏的名字。宏名单独占一行,当源程序被汇
编时,汇编程序将对宏调用进行宏体复制,并取代宏名, 这种复制操作称为宏展开。为了与源程序的其它部分相区
别,后面的叙述中,对由宏调用而展开后得到的指令,都
7.3 宏
程序中使用宏分为定义和调用两个部分。宏定义用来说
明哪些指令或伪指令是将在程序中重复出现的程序段;宏调
相关文档
最新文档