第6章 汇编语言
6.1 实方式执行环境
6.2 源程序和语句
6.3 操作数表示
6.4 伪指令语句和变量
6.5 段声明和段间转移
6.6 目标文件和段模式
6.7 宏
汇编语言!
汇编语言!
6.5 宏
.
宏
指
用
一个符号表示多个符号,或者代码
片段。
.
在
源程序中使用
宏的优点:
.
可以
减少重复书写,简化
源程序
.
可以
实现整体替换,维护
源程序
.宏指用一个符号表示多个符号,或者代码片段。
.在源程序中使用宏的优点:
.可以减少重复书写,简化源程序
.可以实现整体替换,维护源程序
汇编语言的宏,
类似于高级语言的宏
汇编语言的宏,
类似于高级语言的宏
6.7 宏
6.7.1 宏指令的声明和使用
6.7.2 单行宏的声明和使用
6.7.3 宏相关方法
汇编语言的宏
类似于高级语言的宏
汇编语言的宏
类似于高级语言的宏
6.7.1 宏指令的声明和使用
.宏指令的声明
.
声明格式
%
macro
宏指令名
参数
个数
......
%
endmacro
.声明格式
%macro 宏指令名 参数个数
......
%endmacro
一对指示
一对指示
宏指令
宏指令
.
概念
宏指令的声明
指,
说明宏指令(宏)与
由它代表的多个符
号或代码片段之间的替代
关系。
.概念
宏指令的声明指,说明宏指令(宏)与由它代表的多个符
号或代码片段之间的替代关系。
宏指令
的
声明
并
不
占用存储空间
,
称其“声明”
,而非“定义”
宏指令的声明并不占用存储空间,
称其“声明”,而非“定义”
6.7.1 宏指令的声明和使用
.宏指令的声明
一对指示
一对指示
宏指令
GetChar
,
没有参数
宏指令GetChar,
没有参数
声明一个宏,其接受从键盘输入一个键
%
macro
GetChar
0
MOV
AH, 1
INT
21H
%
endmacro
%macro GetChar 0
MOV AH, 1
INT 21H
%endmacro
6.7.1 宏指令的声明和使用
.宏指令的声明
宏指令
PutChar
,
1
个参数
宏指令PutChar,
1个参数
声明一个宏,其显示输出一个字符
一对指示
一对指示
%
macro
PutChar
1
MOV
DL,
%1
MOV
AH, 2
INT 21H
%
endmacro
%macro PutChar 1
MOV DL, %1
MOV AH, 2
INT 21H
%endmacro
6.7.1 宏指令的声明和使用
.宏指令的声明
一对指示
一对指示
宏指令
MOVED
,
2
个参数,分别代表源和目标
宏指令MOVED,
2个参数,分别代表源和目标
声明一个宏,其把一个双字存储单元的内容,
送到另一个存储单元
%
macro
MOVED
2
PUSH
EAX
MOV
EAX,
%2
MOV
%1
, EAX
POP EAX
%
endmacro
%macro MOVED 2
PUSH EAX
MOV EAX, %2
MOV %1, EAX
POP EAX
%endmacro
6.7.1 宏指令的声明和使用
.宏指令的使用
.
调用
格式
宏指令
名
参数表
.调用格式
宏指令名 参数表
.
所谓
宏调用
指,在
声明宏指令后
,使用
宏指令来表示对
应的程序
片段。
.所谓宏调用指,在声明宏指令后,使用宏指令来表示对
应的程序片段。
.
调用示例
GetChar
MOV
BH, AL
PutChar
0DH
PutChar
0AH
.调用示例
GetChar
MOV BH, AL
PutChar 0DH
PutChar 0AH
宏调用
,
有点像函数调用,或子程序调用
宏调用,
有点像函数调用,或子程序调用
.
汇编
时汇编器
把
宏
指
令
还原
成对应
的宏体
(
代码片段
)
,这被称
为
宏展开
,或
宏扩展
。
.汇编时汇编器把宏指
令还原成对应的宏体
(代码片段),这被称
为宏展开,或宏扩展。
6.7.1 宏指令的声明和使用
.宏指令的使用
.
调用示例
GetChar
MOV
BH, AL
PutChar
0DH
PutChar
0AH
.调用示例
GetChar
MOV BH, AL
PutChar 0DH
PutChar 0AH
MOV
AH,
1
INT 21H
MOV
BH, AL
MOV
DL,
0DH
MOV
AH,
2
INT 21H
MOV
DL,
0AH
MOV
AH,
2
INT 21H
MOV AH, 1
INT 21H
MOV BH, AL
MOV DL, 0DH
MOV AH, 2
INT 21H
MOV DL, 0AH
MOV AH, 2
INT 21H
宏展开之结果
宏展开之结果
6.7.1 宏指令的声明和使用
.宏指令的使用
.
调用示例
GetChar
MOV
BH, AL
PutChar
0DH
PutChar
0AH
.调用示例
GetChar
MOV BH, AL
PutChar 0DH
PutChar 0AH
MOV
AH,
1
INT 21H
MOV
BH, AL
MOV
DL,
0DH
MOV
AH,
2
INT 21H
MOV
DL,
0AH
MOV
AH,
2
INT 21H
MOV AH, 1
INT 21H
MOV BH, AL
MOV DL, 0DH
MOV AH, 2
INT 21H
MOV DL, 0AH
MOV AH, 2
INT 21H
宏展开之结果
宏展开之结果
在宏调用时,通常参数
表中
的参数个数应该与声明宏指
令时一致
在宏调用时,通常参数表中
的参数个数应该与声明宏指
令时一致
参数
原样替换
参数
原样替换
6.7.1 宏指令的声明和使用
.宏指令的使用
;
宏
GetChar
和
PutChar
的声明
;
%
macro
TOASC
0
AND
AL, 0FH
ADD
AL, '0'
CMP
AL, '9'
JBE
SHORT
$+4
;
跳过其后加
7
指令
ADD
AL, 7
%
endmacro
;宏GetChar和PutChar的声明
;
%macro TOASC 0
AND AL, 0FH
ADD AL, '0'
CMP AL, '9'
JBE SHORT $+4 ;跳过其后加7指令
ADD AL, 7
%endmacro
编写一个程序,以十六进制数的形式显示所按键的
ASCII
码
。(应用宏指令)
编写一个程序,以十六进制数的形式显示所按键的
ASCII码。(应用宏指令)
宏指令
TOASC
,
把
十六进制数转成对应字符的
ASCII
码
宏指令TOASC,
把十六进制数转成对应字符的ASCII码
安排
2
个宏
安排2个宏
6.7.1 宏指令的声明和使用
.宏指令的使用
SECTION TEXT
;
开始一个段
TEXT
BITS
16
;
16
位段
ORG 100H
;
起始偏移
100H
begin
:
GetChar
;
接受一个键
MOV
BH, AL
;
临时保存
PutChar
0DH
;
形成回车
PutChar
0AH
;
形成
换行
SECTION TEXT ;开始一个段TEXT
BITS 16 ;16位段
ORG 100H ;起始偏移100H
begin:
GetChar ;接受一个键
MOV BH, AL ;临时保存
PutChar 0DH ;形成回车
PutChar 0AH ;形成换行
编写一个程序,以十六进制数的形式显示所按键的
ASCII
码
。(应用宏指令)
编写一个程序,以十六进制数的形式显示所按键的
ASCII码。(应用宏指令)
6.7.1 宏指令的声明和使用
.宏指令的使用
MOV
AL, BH
SHR
AL, 4
;
得到高
4
位
TOASC
;
把高
4
位转成对应
ASCII
码
PutChar
AL
;
显示之
MOV
AL, BH
TOASC
;
把低
4
位转成对应
ASCII
码
PutChar
AL
;
显示之
;
MOV
AH,4CH
;
结束返回操作系统
INT
21H
MOV AL, BH
SHR AL, 4 ;得到高4位
TOASC ;把高4位转成对应ASCII码
PutChar AL ;显示之
MOV AL, BH
TOASC ;把低4位转成对应ASCII码
PutChar AL ;显示之
;
MOV AH,4CH ;结束返回操作系统
INT 21H
编写一个程序,以十六进制数的形式显示所按键的
ASCII
码
。(应用宏指令)
编写一个程序,以十六进制数的形式显示所按键的
ASCII码。(应用宏指令)
6.7.1 宏指令的声明和使用
.宏指令的用途
.
简化源代码
.
扩充
指令集
.
改变指令
助记符的意义
.简化源代码
.扩充指令集
.改变指令助记符的意义
6.7.2 单行宏的声明和使用
.单行宏的声明
.
声明格式
%define
宏名(参数表)
宏
体
.声明格式
%define 宏名(参数表) 宏体
指示
指示 包含参数的表达式
包含参数的表达式
.
单行宏
指,一个符号代表多
个
符号,由一行表示之。
.单行宏指,一个符号代表多个符号,由一行表示之。
可以没有参数表,如果没有参数表,
那么也不需要圆括号
可以没有参数表,如果没有参数表,
那么也不需要圆括号
6.7.2 单行宏的声明和使用
.单行宏的声明
.
声明格式
%define
宏名(参数表)
宏
体
.声明格式
%define 宏名(参数表) 宏体
.
声明
示例
%
define
count
12
%define
move
MOV
%define
cleax
XOR EAX, EAX
.声明示例
%define count 12
%define move MOV
%define cleax XOR EAX, EAX
6.7.2 单行宏的声明和使用
.单行宏的使用
.
声明之示例
%
define
count
12
%define
move
MOV
%define
cleax
XOR EAX, EAX
.声明之示例
%define count 12
%define move MOV
%define cleax XOR EAX, EAX
.
使用之示例
MOV
CX,
count
move
EAX, EBX
cleax
move
esi
,
count
move
dx,
count
+ 3
.使用之示例
MOV CX, count
move EAX, EBX
cleax
move esi, count
move dx, count + 3
.
展开之结果
MOV
CX,
12
MOV
EAX, EBX
XOR
EAX, EAX
MOV
esi
,
12
MOV
dx
,
12
+ 3
.展开之结果
MOV CX, 12
MOV EAX, EBX
XOR EAX, EAX
MOV esi, 12
MOV dx, 12 + 3
6.7.2 单行宏的声明和使用
.单行宏的应用
.
声明
%
define
lvar
(
n
)
[EBP
-
4*
n
]
%
define
array(
a
,
i
)
dword
[
a
+4*
i
]
.声明
%define lvar(n) [EBP-4*n]
%define array(a,i) dword [a+4*i]
.
调用
MOV
AL,
lvar
(
1
)
MOV EDX,
lvar
(
2
)
MOV EAX,
array(
ECX
,
3
)
MOV ECX,
array(
EBX
,
ESI
)
.调用
MOV AL, lvar(1)
MOV EDX, lvar(2)
MOV EAX, array(ECX, 3)
MOV ECX, array(EBX, ESI)
.
展开
MOV
AL,
[EBP
-
4*
1
]
MOV
EDX,
[EBP
-
4*
2
]
MOV
EAX,
dword
[
ECX
+4*
3
]
MOV
ECX,
dword
[
EBX
+4*
ESI
]
.展开
MOV AL, [EBP-4*1]
MOV EDX, [EBP-4*2]
MOV EAX, dword [ECX+4*3]
MOV ECX, dword [EBX+4*ESI]
参数
原样替换
参数
原样替换
6.7.3 宏相关方法
.宏相关的方法
.
宏
名的“脱敏”
.
宏体中的标号
.
宏
的
嵌套
.
灵活
的宏
参数
.
条件码作为宏参数
.宏名的“脱敏”
.宏体中的标号
.宏的嵌套
.灵活的宏参数
.条件码作为宏参数
符号不完全一致
符号不完全一致
6.7.3 宏相关方法
.宏名的“脱敏”
如何使
宏(指令)名
大小写不敏感?
如何使宏(指令)名大小写不敏感?
MOV
AX,
123
+1
ADD
BX, [
SI+
123
]
MOV CX,
AB
c
ADD DX,
abc
MOV AX, 123+1
ADD BX, [SI+123]
MOV CX, ABc
ADD DX, abc
没有替换(扩展)
没有替换(扩展)
%define ABC 123
MOV AX
, ABC+1
ADD
BX, [SI+ABC]
MOV CX,
A
B
c
ADD DX,
abc
%define ABC 123
MOV AX, ABC+1
ADD BX, [SI+ABC]
MOV CX, ABc
ADD DX, abc
.
问题
.问题
应用符号常量
ABC
应用符号常量ABC
符号不完全一致
符号不完全一致
6.7.3 宏相关方法
.宏名的“脱敏”
在声明时,指示符中增加
字母
i
在声明时,指示符中增加字母i
MOV
AX,
123
+1
ADD
BX, [
SI+
123
]
MOV CX,
123
ADD DX,
123
MOV AX, 123+1
ADD BX, [SI+123]
MOV CX, 123
ADD DX, 123
%
i
define
ABC 123
MOV AX
, ABC+1
ADD
BX, [SI+ABC]
MOV CX,
A
B
c
ADD DX,
abc
%idefine ABC 123
MOV AX, ABC+1
ADD BX, [SI+ABC]
MOV CX, ABc
ADD DX, abc
.
解决方案
.解决方案
指令名大小写字母混合
指令名大小写字母混合
6.7.3 宏相关方法
.宏名的“脱敏”
在声明时,指示符中增加
字母
i
在声明时,指示符中增加字母i
push
9
pop
EBX
push 9
pop EBX
%
i
macro
movei
2
push %
2
pop
%1
%
endmacro
;
MOVEi
EBX, 9
%imacro movei 2
push %2
pop %1
%endmacro
;
MOVEi EBX, 9
.
解决方案
.解决方案
一个利用堆栈传递立即数的宏
一个利用堆栈传递立即数的宏
6.7.3 宏相关方法
.宏体中的标号
如何在宏体中使用标号?
如何在宏体中使用标号?
%
macro
TOASC
0
AND
AL, 0FH
ADD
AL, '0'
CMP
AL, '9'
JBE
SHORT
$+
4
ADD AL, 7
%
endmacro
%macro TOASC 0
AND AL, 0FH
ADD AL, '0'
CMP AL, '9'
JBE SHORT $+4
ADD AL, 7
%endmacro
跳过其后的
4
字节
跳过其后的4字节
%
macro
TOASC
0
AND
AL, 0FH
ADD
AL, '0'
CMP
AL, '9'
JBE
SHORT
OK
ADD AL, 7
OK:
%
endmacro
%macro TOASC 0
AND AL, 0FH
ADD AL, '0'
CMP AL, '9'
JBE SHORT OK
ADD AL, 7
OK:
%endmacro 会引起
标号重复出现
会引起标号重复出现
.
问题
.问题
十六进制数转成对应
ASCII
码的宏
十六进制数转成对应ASCII码的宏
6.7.3 宏相关方法
.宏体中的标号
在标号前加记号
%%
在标号前加记号 %%
%
macro
TOASC
0
AND
AL, 0FH
ADD
AL, '0'
CMP
AL, '9'
JBE
SHORT
OK
ADD AL, 7
OK:
%
endmacro
%macro TOASC 0
AND AL, 0FH
ADD AL, '0'
CMP AL, '9'
JBE SHORT OK
ADD AL, 7
OK:
%endmacro 会引起
标号重复出现
会引起标号重复出现
.
解决方案
.解决方案
十六进制数转成对应
ASCII
码的宏
十六进制数转成对应ASCII码的宏
%
macro
TOASC
0
AND
AL, 0FH
ADD
AL, '0'
CMP
AL, '9'
JBE
SHORT
%%
O
K
ADD AL, 7
%%OK:
%
endmacro
%macro TOASC 0
AND AL, 0FH
ADD AL, '0'
CMP AL, '9'
JBE SHORT %%OK
ADD AL, 7
%%OK:
%endmacro
6.7.3 宏相关方法
.宏的嵌套
假设已声明宏
PutChar
假设已声明宏PutChar
.
宏嵌套
指在宏体中包含有宏调用。
.宏嵌套指在宏体中包含有宏调用。
一个产生回车换行效果的宏
NewLine
一个产生回车换行效果的宏NewLine
%
macro
NewLine
0
PutChar
13
PutChar
10
%
endmacro
%macro NewLine 0
PutChar 13
PutChar 10
%endmacro
%
macro
PutChar
1
MOV
DL, %1
MOV
AH, 2
INT 21H
%
endmacro
%macro PutChar 1
MOV DL, %1
MOV AH, 2
INT 21H
%endmacro
宏体中含有其他宏
宏体中含有其他宏
6.7.3 宏相关方法
.宏的嵌套
.
宏嵌套
指在宏体中包含有宏调用。
.宏嵌套指在宏体中包含有宏调用。
一个产生回车换行效果的宏
NewLine
一个产生回车换行效果的宏NewLine
%
macro
NewLine
0
PutChar
13
PutChar
10
%
endmacro
;
NewLine
%macro NewLine 0
PutChar 13
PutChar 10
%endmacro
;
NewLine
MOV
DL,
13
MOV
AH, 2
INT
21H
MOV
DL,
10
MOV
AH, 2
INT
21H
MOV DL, 13
MOV AH, 2
INT 21H
MOV DL, 10
MOV AH, 2
INT 21H
参数
原样替换
参数
原样替换