汇编语言宏指令
《汇编语言程序设计》第7章 高级宏语言

7.1 宏指令
宏嵌套
1. 宏定义中可以嵌套宏调用 2. 宏定义中可以嵌套宏定义
7.1 宏指令
宏嵌套
1. 宏定义中可以嵌套宏调用 例7.4 非组合BCD码转换成ASCII码。
宏定义: TURN MACRO ADD AL,30H ENDM BTOA MACRO ADDR XCHG AL,ADDR TURN XCHG AL,ADDR ENDM 宏调用: BTOA DATA 宏展开: + XCHG AL,DATA + ADD AL,30H + XCHG AL,DATA
7.2 条件汇编指令
宏定义与宏结束指令
⑥IFNDEF CONT 此操作中的条件CONT是一个符号,如果这个符号未定义,或未经 EXTRN伪指令说明,则条件为真。 ⑦IFB <CONT> 如果尖括号中为空(不写任何字符),则条件为真。 ⑧IFNB <CONT> 如果尖括号中不为空,则条件为真。 ⑨IFIDN <CHR1>,<CHR2> CHR1和CHR2为字符串,如果两个字符串相同,则条件为真。两个 字符串必须分别用尖括号括起来。 ⑩IFDIF <CHR1>,<CHR2> CHR1和CHR2为字符串,如果两个字符串不相同,则条件为真。两 个字符串必须分别用尖括号括起来。
7.1 宏指令
宏定义与宏结束指令
3.宏指令的有效范围 宏指令的优先级最高。可以定义与指令助记符、伪操作 同名的宏,此时,同名机器指令或伪操作失效。只有用 PURGE伪操作取消宏定义,才能恢复同名机器指令或伪 操作的原始含义。 PURGE伪操作可同时取消多个宏定义,被取消的宏名之 间用逗号分隔。格式为:
7.3 重复汇编指令
第08章 条件汇编与宏指令

8.1.1 宏定义与宏结束伪操作命令
1、宏定义的一般格式 MNAME MACRO [形参1],[形参2]...... : : } 宏体 : ENDM 功能:定义一个新指令(宏名字),并用这个新指令来代表宏体全部内容。 说明: 1)宏指令一定要先定义,后调用。因此,宏定义一定要放在它的第一次 调用之前。 2)宏指令名可以与伪指令、机器指令的助记符同名且具有比指令、伪指 令更高的优先权。如果需要对某一宏指令重新定义,则直接重新定义即可 。 3)允许对已定义好的宏定义取消定义,其取消宏定义伪指令格式: PURGE 宏指令名[,宏指令名] 宏定义一旦取消就不能再调用。
注意:%后的符号一定是直接用EQU或等号(=)赋值的符号常量,或者汇编时能计算 出值的表达式,而不能是变量名和寄存器名。
汇编语言 程序设计
四、感叹号操作符 !
• 当把“&”、“%”这样的符号当作一个普通字符使用时, 要想使宏功能不将它们当作特殊宏操作符看待,必须在它 们前面加上操作符!。 • 例如有宏定义: • DISP MACRO X • DB ‘ abc!&x=&x’ • ENDM • 若进行如下宏调用: • A EQU 5 • DISP %A • 则相应的宏扩展为: • DB ‘ abc &x=5’
SHIFT 4,AL,AX SHIFT 2,AR,BH SHIFT 5,HR,DX 则在汇编这些宏指令语句时,所得到的宏扩展为: 1 MOV CL,4 1 SAL AX,CL ;将AX内容算术左移位 1 MOV CL,2 1 SAR BH,CL ;将BH 内容算术右移2位 1 MOV CL,5 1 SHR DX,CL ;将DX内容逻辑右移5位
汇编语言 程序设计 • • •
宏中标号的处理
汇编语言——第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Ⅱ码形式寄存在相应的存储单元,但表示形式各不相同。
第三章 宏汇编语言

3.2.1 常量
1.数值常量 . 2. 符号常量
返回本节
1.数值常量 .
数值类型常量有二进制、八进制、 数值类型常量有二进制、八进制、十进制和十六进制数 常量有二进制 字形式和字符串形式的常量。 字形式和字符串形式的常量。
表3.1
各种形式数字常量格式对照表 汇编语言大小写不敏感> <汇编语言大小写不敏感>
表达式: 表达式: 表达式项是给变量或指定存储单元赋予初值 , 表达式项 是给变量或指定存储单元赋予初值, 它 是给变量或指定存储单元赋予初值 有以下几种形式: 有以下几种形式: (1)数值表达式 ) (2) 字符串表达式 ) 两个伪指令) (3)地址表达式(只适用 )地址表达式(只适用DW和DD两个伪指令) 和 两个伪指令 (4)? 表达式 ) (5)带DUP的表达式 ) 的表达式
返回本节
2. 符号常量
• 对经常使用的数值常量可以先为它定义一个名字, 对经常使用的数值常量可以先为它定义一个名字, 然后在语句中用名字来表示该常量。 然后在语句中用名字来表示该常量。常数若使用 符号名来表示 有意义的符号名来表示,可以提高程序的可读性, 有意义的符号名来表示,可以提高程序的可读性, 同时更具有通用性。 同时更具有通用性。
3.关系运算符 .
关系运算符包括:相等( ),不等( ),小于( ), ),不等 ),小于 关系运算符包括:相等(EQ),不等(NE),小于(LT), 大于( ),小于等于( )及大于等于( )。 ),小于等于 大于(GT),小于等于(LE)及大于等于(GE)。 运算结果:若关系不成立,结果为 ;否则为0FFFFH。 运算结果:若关系不成立,结果为0;否则为 。 【例3.3】用关系运算符进行数值表达式运算。 】用关系运算符进行数值表达式运算。 NUM1 DB 10 LT 5 NUM2 DB 0AAAAH GT 7FFFH MOV AX,‘A‘ EQ 41H , MOV BX,NUM2 LT NUM1 , 结果: 结果:NUM1=0 ; NUM2=0FFH; (AX)=0FFFFH; (BX)=0
华中科技大学8086汇编讲义第三章宏汇编语言

第三章宏汇编语言每种计算机语言都规定了自己的字符、基本词汇、典型语句和语法规则。
同样,汇编语言也有自己的字符、基本词汇、典型语句和语法规则。
字符:ASCII字符基本词汇:符号指令(MOV、ADD)伪指令(DB、SEGMENT等)典型语句:●机器指令语句——对应机器指令的一种操作。
●伪指令语句——无机器语言与之对应,不生成机器指令。
●宏指令语句——一条宏指令对应多条机器指令,产生一组目标代码。
语法规则:基本语法单位(常量、变量、标号、表达式)前面的例子已介绍了源程序的基本结构、格式、名字的定义、语句格式,下面将更深入地介绍有关语法规则。
3.1表达式汇编程序的语句及程序格式都比较固定,语句中除正确选择操作符之外,主要问题在于正确表示操作数地址,这涉及到寻址方式,可以归结到地址表达式的使用。
表达式:由常数、寄存器、标号、变量加上运算符构成的式子。
3.1.1.常量与数值表达式一.常量常量:从源程序翻译成目标程序期间已经有确定数值的量。
用途:赋值、作立即数、位移量。
由常量与运算符组成的式子。
数值表达式在汇编期间进行运算,结果为常量。
汇编期间允许对常量进行3种运算:1.算术运算包括:+、–、*、/、模除(MOD,取余数)、右移、左移。
2.逻辑运算●逻辑乘:AND(与)●逻辑加:OR(或)●按位加:XOR(异或)●逻辑非:NOT(非)3.关系运算包括:相等(EQ)、不等(NE)、小于(L T)、大于(GT)、小于等于(LE)、大于等于(GE)。
运算结果:关系不成立,结果为0;关系成立,结果为–1(0FFFFH)。
如:N = 50M = (N EQ 50)该关系成立,M =–1。
3.1.2.变量、标号与地址表达式一.变量变量:数据存贮单元的名字。
(存放地址的符号表示)。
变量有三个属性:段、EA、类型。
其中类型由定义时的伪指令确定(DB、DW、DD、DT)。
变量的定义:格式:[变量名] 数据定义伪指令表达式[,…]数据定义伪指令:DB、DW、DD、DQ、DT等。
8086汇编语言语句的类型和格式

⑴ 算术运算符:+、-、*、/和取模运算。
⑵ 逻辑运算符:、、和。
⑶ 关系运算符:、、、、、。结果只有两个全 1或全0。
⑷ 分析运算符:利用分析运算符可以把一个存 储单元地址分解为段地址和偏移地址等。分析运算符 有 、 、、和等。
分析运算符表达式
带分析运算符的表达式
: ,2[] ;取一个字节加数 1 0F8H,60H,0,74H,3 ;被加数 第一条语句是指令语句,其中“:”是名字,“”是指令助记符, “,2[]”是操作数,“;”后面是注释部分;第二条语句是伪指 令语句,其中“1”是名字,“”是伪指令定义符,“0F8H, 60H,0,74H,3”是操作数,“;”后面是注释部分。
⑵ 定义变量的类型为,给变量分配字操作数。
⑶ 定义变量的类型为,给变量分配双字操作 数。
除了常数、表达式和字符串外,问号“?”也 可以作为数据定义伪指令的操作数,此时仅给变量保 留相应的存储单元,而不赋与变量某个确定的初值。
当同样的操作数重复多次时,可用重复操作符 “”表示,其形式为:
n (初值[,初值…0])
1) 名字
汇编语言语句的第一个组成部分是名字()。在指令语句 中,这个名字是一个标号。指令语句中的标号实质上是指“:”后 面指令所在的存储地址(逻辑地址)。供、和等指令作操作数使用, 以寻找转移目标地址。并非每条指令语句必须有标号,但如果 一条指令前面有一标号,则程序中其它地方就可以引用这个标 号。在例5.1中,、就是标号。标号后面有一个冒号。
• , K3
;()←20H,返回前面的数值
• , K4
;()←01H
• , K3
;()←40H
• , K4
;()←04H
汇编语言——宏

【例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)宏定义可以写在程序的任何地方,但习惯上总是把 宏定义写在程序的最前面。 宏定义与编辑器中的文字块的定义有相似之处,也有一 些差别。两者都需要以特定的方式说明开始和结束的位置。 文字块是文件的一部分,而宏体中的程序段必须经过宏调用 才能复制到源程序中正确的位置,没有被调用的宏体在汇编 程序翻译时会被忽略。
汇编语言——宏

因此,对这一类错误提示,程序员只能自己按规则进行宏展 开,并判断展开后的结果是如何出的错。对于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
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ENDM 宏调用:
… ADD X , Y , Z
;使用宏ADD
PURGE ADD …
;使用指令ADD
当然,最后能不能达成所愿,还要具体看编译器是怎么来支持 的!
6. 宏定义的嵌套 宏定义的嵌套有两种情况:宏定义体中含宏调用;宏定义体中 含宏定义。 (1)宏定义体中宏调用 宏汇编语言允许在宏定义体中使用宏调用,但限制条件是:必 须先定义后调用。 例如: DIF MACRO X , Y ; X – Y 送 AX
??0001: …
(2) 清除宏定义的为指令PURGE
格式: PURGE 宏名表
例如:
…
AAA MACRO
…
ENDM
…
…
;宏AAA可以有效使用的区间
…
PURGE AAA
…
…
;宏AAA不可有效地使用
…
例:利用宏指令修改某些助记符意义
宏定义:
ADD MACRO OP1 , OP2 , RESULT
…
例如,把通过DOS的1功能调用从键盘读入一个字符的程序片 段定义为一个宏:
GETCH MACRO
MOV AH , 1 INT 21H ;从键盘键入一个字符时,该字符存入AL
ENDM
在定义宏指令后,就可以通过宏指令来表示对应的程序片段, 这成为宏调用。其格式为:
宏指令名 [实参表]
在对源程序汇编时,汇编程序把程序中的宏指令替换成对应的 宏定义体,这称为宏展开或宏扩展。如:
(2)表达式运算符 % 在宏调用时,使用该运算符把其后表达式的结果作为宏参替换,
而非表达式自身。 宏MSGGEN的定义方式如上例。 则调用 MSGGEN MSG , %(2 + 3) , ‘TOM’ 展开为:
MSG5 DB ‘HELLO MR.TOM’ , 0DH , 0AH , 24H
5. 与宏有关的伪指令 (1)局部标号说明伪指令 LOCAL 格式:LOCAL 标号表 标号表由标号构成,标号间用逗号分隔。 汇编程序在每次展开时,总把由LOCAL伪指令说明的标号用 唯一的符号(??0000至??FFFF)代替,从而避免标号重 定义错误。 例如:定义一个取绝对值的宏
SAL AL , CL 如上述代码要多次使用,就可以定义为: SHIFT MACRO
MOV CL , 4 SAL AL , CL ENDM
但是,如果每次的移位次数不同了,则可定义为: SHIFT MACRO X ;X为参数
MOV CL , X SAL AL , CL ENDM 这是,调用方式可为: SHIFT 4 ;移4位 SHIFT 6 ;移6位,显然,有参数时使用起来更灵活。 2. 宏指令的参数可以是操作码 例如:有下面的宏定义:
(2)宏定义体中定义宏指令
宏定义体中还允许包含宏定义,但是只有在调用了外围的宏后, 才能调用内层的宏。
MOV AX , X
SUB AX , Y
ENDM
DIFSQR MACRO OPR1 , OPR2 , RESULT; ( X – Y)2 送 AX
PUSH DX
PUSH AX
|
POP AX
DIF OPR1 , OPR2 ;注意堆栈 |
POP DX
IMUL AX
|
ENDM
MOV RESULT , AX
ABSOL MACRO OPER LOCAL NEXT CMP OPER , 0 JGE NEXT NEG OPER
NEXT: ENDM
宏调用 ABSOL VAR ABSOL BX
时,宏展开: … ;主程序中的代码段 … CMP VAR , 0 JGE ??0000 NEG VAR
??0000: CMP BX , 0 JGE ??0001 NEG BX
4. 两个特殊的宏运算符 (1)强迫替换运算符 & 在宏定义中,若参数在其它字符的紧前或紧后,或者参数出现 在带引号的字符串中时,就必须使用该运算符,以区分参数。 例:在下面宏指令JUMP中,参数CON作为操作码一部分。 JUMP MACRO CON , LAB
J&CON LAB ENDM 则调用时,JUMP NZ HEAR -> JNZ HEAR JUMP Z , THERE -> JZ THERE
例:在下面宏指令MSGGEN中,两个参数合并成一个标号, 一个参数用在字符串中。 MSGGEN MACRO LAB , NUM , XYZ
LAB&NUM DB ‘HELLO MR.&XYZ’ , 0DH , 0AH , 24H MSGGEN 则调用 MSGGEN MSG , 1 , TAYLOR 展开为:MSG1 DB ‘HELLO MR.TAYLOR’ , 0DH , 0AH , 24H
……
….
GETCH
对应为 --->
MOV AH , 1
……
INT 21H
…
尽管都实现了调用,但是宏调用和子程序的调用是有差别的:
宏调用更多地是表示一种替换!
(二)宏指令的用途 1. 缩短源代码 2. 扩充指令集 3. 更改某些指令助记符的意义 (宏指令的优先级高于指令和伪指令)
(三)宏指令中参数的使用 宏指令可以不带参数,但往往带有参数的宏指令更具灵活性。 1. 指令的参数可以是常数、寄存器和存储单元,还可以是表达 式。 例: MOV CL , 4
“SHIFT 6 , BX , AR” 或 “SHIFT 8 , SI , HR ”等等。
3. 宏调用参数个数可以与定义时不一致 正常情况下,宏调用时使用的实参个数应该与宏定义时的形参 个数一致,但汇编程序并不要求他们它们必须相等。 若实参个数多于形参个数,那么多余的实参被忽略; 若实参个数少于形参的个数,那么多余的形参用“空”代替。
参数还可以是操作码的一部分:
SHIFT MACRO X , Y , Z
MOV CL , X
S&Z Y , CL
;&起符连接作用
ENDM
调用:SHIFT 4 , AL , AL 展开为:
MOV CL , 4 ;4为参数X
SAL AL , CL ;第1个“AL”为参数Z,第2个“AL”为参数Y
该宏的调用方式还可以是:
MANDM MACRO OPR , X , Y MOV AX , X OPR AX , Y MOV X , AX
ENDM 该宏定义的意思是?????
改宏被调用和展开的时候,意义就明确了。如: MANDM MOV , [BX] , [SI] MANDM ADD , [BX] , ES:[1234H]