第四章 汇编语言程序设计 - 北京大学微处理
Download
Report
Transcript 第四章 汇编语言程序设计 - 北京大学微处理
第7章 汇编语言的基本语法
Assemble Language
一种面向机器的程序设计语言,是一种用符号表
示的低级程序设计语言(机器语言的符号化描
述),通常是为特定计算机或计算机系列专门设
计的。
Assemble Language
用汇编语言编写的程序不
能由机器直接执行,而必
须经汇编程序翻译成机器
语言程序。汇编语言指令
与翻译成的机器语言指令
之间基本是一一对应的关
系。
汇编过程示意:
采用汇编语言进行程序设计的优点:
可充分利用机器的硬件功能和结构特点,加快程序的执行
速度,减少目标程序所占用的存储空间。
常用来编写实时控制程序、实时通信程序,有时也用来编
制某些系统软件程序。
缺点:
1. 编程效率低(与人们描述计算过程的需要差距大);
2. 与机器硬件的具体结构联系过于紧密
——在一种结构的机器上开发的程序极难移植到另一
种不同结构的机器上去。
示例程序
DATA SEGMENT
;数据段
NUM DW 0011101000000111B
NOTES DB ‘The result is :’ , ’$’
DATA ENDS
CODE SEGMENT
;代码段
ASSUME CS:CODE,DS:DATA
BEGIN:
MOV AX, DATA
MOV DS,AX
MOV DX,OFFSET NOTES ;显示提示信息
MOV AH,9H
INT 21H
MOV BX,NUM
;将数装入BX
MOV CH,4
;CH作循环计数器
示例程序(续)
ROTATE :
DISPLAY:
MOV CL, 4
;CL中放移位位数
MOV DL, AL ;显示16进制数
ROL BX,CL
MOV AH,2
MOV AL,BL
INT 21H
AND AL,0FH ;AL中为一位16进制数 DEC CH
ADD AL,30H ;转换为ASCII码值
JNZ ROTATE
CMP AL,’9’
;是0~9的数码?
MOV AX,4C00H;返回DOS
JLE DISPLAY
INT 21H
ADD AL,07H ;在A~F之间
CODE ENDS
;代码段结束
END BEGIN ;模块结束
堆栈段定义格式
STACK SEGMENT STACK
STA DB 50 DUP (?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS, AX
MOV SP,TOP
:
CODE ENDS
END START
7.1.2 汇编语言源程序的组成
1. 伪指令语句和指令语句
汇编语言源程序中除了包含真正的指令外,还应包含说明
性的“指令”。这些说明性的“指令”是面向汇编程序和
连接程序的,称为伪指令。
宏汇编程序5.0版(MASM V5.0)规定,汇编语言源程序的
每行只能写一个语句: 指令语句或伪指令语句。行长不
能超过128个字符。每个语句最多可由四个字段组成: 名
字字段、操作字段、操作数字段和注释字段。
伪指令语句是说明性语句,其格式为:
[名字]伪指令说明符[参数表达式1[,参数表达式2[,…… ]]]
[;注释]
其中,伪指令说明符(伪指令名)是伪指令语句中不可缺少
的主体,其余部分(方括号中的内容)有时可省略。
名字可为段名、过程名、变量名、符号名(或常量名)、宏
名、结构名、记录名等。
例:
A DB 20H,30H ; 注释
指令语句是可执行语句,其格式为:
[名字:]指令操作助记符[操作数表达式1[,操作数表达式2]][;注释]
其中,指令操作助记符(指令名)是指令语句中不可缺少的
主体,其余部分(方括号中的内容)有时可省略。
名字只能是标号。
注释以分号开头,分号右边的内容将被汇编程序忽略。
例
L: ADD AX,BX ;注释
汇编程序负责计算伪指令语句中表达式的值,解释伪指令
语句的含义并遵照“执行”,但并不产生机器代码。
汇编程序负责计算指令语句中表达式的值,并将汇编指令
翻译成机器指令代码。
指令语句经汇编后,在可执行程序运行期间由CPU解释,
并由CPU按指令的要求完成各种运算与操作。
7.1.4 汇编语言的表达式
1. 汇编语言的标识符
2. 汇编语言的操作对象( 数据类型)
(1) 常数、常量
编程时已经确定其值,程序运行期间不会改变其值的数据
对象称为常数。
8086/8088CPU允许定义四种形式的常数: 整数、字符串、
“组合BCD码数”和实数(浮点数),但只能处理整数、字
符串、“组合BCD码数”,不能处理实数(浮点数)。
常数表达式的名字称为常量。
(程序员给出的一个名或助记名作为一个确定值的标识,
其值在程序执行过程中保持不变。)
常量可用伪指令说明符“EQU”或“=”定义。
例如,A EQU 7或 A = 7都可将常量A的值定义为常数7。
注意:伪指令说明符EQU左边的符号名不允许重复定义,
而“=”左边的符号名可以重复定义。
即,A EQU 7
可以:A=7
A EQU 8 (不允许)
A=8
(2) 变量
编程时只能确定其初始值,程序运行期间可修改其值的数
据对象称为变量。变量是存储单元中的数据,可定义在任
何段(DS、 ES、 SS、 CS),但通常都定义在数据段(DS)
和附加段(ES)。
变量由伪指令说明符DB、DW、DD等定义。需要时可给
变量的地址取名字,变量名就是变量地址的名字,可称为
变量的符号地址。
例如, 在下列伪指令语句中,
A DB 50,60,70,80
DW 50,60,70,80
DD 50,60,70,80
用DB、DW、DD说明符各定义了4个变量,并给出了每个
变量的初始值。
用DB定义的每个变量占一个字节单元,用DW定义的每个
变量占两个连续的字节单元,用DD定义的每个变量占四
个连续的字节单元,这些变量全部都按定义时的顺序依次
存储,只是用DB定义的第一个变量赋予了名字A。
A仅代表DB右边第一个变量(即DB右边初值为50的变量)
的地址。
变量有如下的属性:
①段基值属性: 指变量所在段的段基值;
②偏移地址属性: 指变量所在的存储单元的段内偏移地址;
③类型属性: 指变量所占存储单元的字节数。
(3) 标号
标号就是指令地址的名字,也称为指令的符号地址。
标号定义在指令的前面(通常是左边),用冒号作为分隔符。
标号只能定义在代码段(CS)中,它代表其后第一条指令的
第一个字节的存储单元地址,用于说明指令在存储器中的
存储位置。例如, 在下列指令序列中,
MOV CX, 2
L:DEC CX
JZ L
L就是标号,它是JZ指令的直接操作数(转移地址).
标号有如下的属性:
①段基值属性: 指标号后面第一条指令所在的代码段的
段基值;
②偏移地址属性: 指标号后面第一条指令首字节的段内
偏移地址;
③类型属性: 也称距离属性,是指标号与引用该标号的
指令之间允许距离的远、近。
(4) 段名
每一个段都必须用SEGMENT和ENDS标识段的开始和结
束,SEGMENT和ENDS左边必须有名字,段名就是
SEGMENT和ENDS左边的名字。
对于同一个段,ENDS左边的名字必须与SEGMENT左边
的名字相同。
(5) 过程名
过程就是一段程序,可以是主程序,也可以是子程序。一
个代码段中可以只有一个过程,也可以有多个过程。
每一个过程都可用PROC和ENDP标识过程的开始和结束,
PROC和ENDP左边必须有名字,过程名就是PROC和
ENDP左边的名字。
对于同一个过程,ENDP左边的名字必须与PROC左边的
名字相同。
过程名等同于标号,具有标号的全部属性。
过程(子程序)的基本结构
Proc-A
过程名
Proc-A
PROC
NEAR(或FAR)
____________
____________
.
.
.
____________
RET
ENDP
(6) 偏移地址计数器$
汇编程序在对源程序进行汇编的过程中,用偏移地址计数
器$来保存当前正在汇编的指令的偏移地址或伪指令语句
中变量的偏移地址。
用户可将$用于自己编写的源程序中。
在每个段开始汇编时,汇编程序( 汇编器)都将$清为0,
以后,每处理一条指令或一个变量,$就增加一个值,此
值为该指令或该变量所占的字节数。
可见,$的内容就是当前指令或变量的偏移地址。
在伪指令中,$代表其所在地的偏移地址。例如,如果A的
偏移地址是0074H,则语句
A DW 1, 2, $+4, 3, 4, $+4 中的第一个$+4的偏移地址为
A+4,第二个$+4的偏移地址为A+10。
汇编后:
第一个$+4:$+4=(A+4)+4=(0074H+4)+4=007CH
第二个$+4:$+4=(A+10)+4=(0074H+0AH)+4=0082H
在指令中,$无论出现在指令的任何位置,都代表本条指
令第一个字节的偏移地址。例如,“JZ $+6”的转向地址
是该指令的首地址加上6,$+6还必须是另一条指令的首地
址。再如,在下述指令序列中,
DEC CX
JZ $+5
MOV AX, 2
LAB: ...
因为$代表JZ指令的开始地址,而JZ指令占2个字节,这
里的MOV 指令占3个字节,所以,在发生转移时,JZ指令
会将程序转向LAB标号处的指令, 且标号LAB 可省。
3. 汇编语言的伪操作(运算)符
汇编语言中的操作符号很多,可分为算术操作符、逻辑操
作符、关系操作符、重复置数(复制)操作符、取属性(分析)
操作符、指定属性(合成)操作符、分离操作符、结构和记
录中专用的操作符等几类。
这些操作符都是面向汇编程序的,都由汇编程序解释并
“执行”,而不是像指令那样由CPU去执行。
通常称这些操作符为伪操作符,称对应的操作为伪操作。
(1) 算术伪操作
常见的有+、-、MOD、SHL、SHR、*、/共7个符号,分
别表示加、减、取模(求余数)、逻辑左移、逻辑右移、乘、
除。这些操作符都可用于数据之间的运算,+、-操作符还
可用于地址之间、数据与地址之间的运算。
用于数据之间的运算时,按每个操作符的定义进行。
例如,在字节操作时,
“124 MOD 3”的结果为1
“10110101B SHL 2”的结果为11010100B
再例如,对如下的定义,
W1 DW 1, 2, 3, 4, 5, 6, 7
B1 DB 10, 20, 30, 40, 50
N1 EQU B1-W1
N2 EQU $-W1
B2 DB 0
则N1=14,它是从W1开始到B1前为止的一组变量的字节
数;
N2=19,它是从W1开始到B2($代表的地址)前为止的一组
变量的字节数。
(2) 关系伪操作
关系伪操作对两个数据进行比较,有EQ、NE、LT、GT、
LE、GE共6个符号,分别表示等于、不等于、小于、大于、
小于或等于、大于或等于,操作的结果为逻辑值。
若条件满足,则结果为“真”,若条件不满足,则结果为
“假”。“真”用-1(n位全1)表示,“假”用0(n位全0)表
示。
例如,在字操作时:
(60H LE 70H) GE (60H LT 30H) = FFFFH GE 0000H =
FFFFH。
(3) 逻辑伪操作
有NOT、AND、OR、XOR共4个符号,分别表示非、与、
或、异或,可用于对两个(或一个)数据进行操作。
例如,在字操作时,1234H OR 2AFEH = 3AFEH,
NOT 0F0H = FF0FH;
在字节操作时,NOT 0F0H = 0FH。
(4) 重复置数(复制)伪操作
只有DUP一个符号,表示对其后(右边)的数据进行重复设
置(复制),使用格式是:
重复次数DUP (初值1[, 初值2[, …… ]])
其中,重复次数为无符号整数(1~65535),初值1、初值
2 …… 为变量的初始值。例如,
下面各行的写法都等效:
W DW 25,8,2,3,2,3,6,8,2,3,2,3,6
W DW 25,2 DUP(8,2,3,2,3,6)
W DW 1 DUP(25),2 DUP(8,2 DUP(2,3),6)
W DW 1 DUP(25),2 DUP(1 DUP(8),2 DUP(2,3),1
DUP(6))
第一行的写法将13个变量分为13组,每组重复1次。后三
行的写法将13个变量分为两组,第一组将25重复一次,第
二组将(8,2,3,2,3,6)重复两次。
无论哪种写法,我们都将第一组变量的重复次数称为W的
长度,将W的长度与W的类型之积称为W的大小。此处,
W的长度为1,类型为2,大小为2。长度和大小也可看作
变量的属性。
练习:若定义A DB 1, 2, 5 DUP(0,1,2 DUP(3)),则在A的
存储区前6个字节单元的数据是
.
(5) 取属性(也称分析)伪操作
取属性伪操作可以取出运算对象的某个属性。常见的有
SEG、OFFSET、TYPE、LENGTH、SIZE共5个符号,
分别表示取段基值、取偏移地址、取类型、取长度、取大
小,操作的结果都是数值常数。
①格式: SEG 变量名或标号
返回变量或标号所在段的段基值。例如,若A为变量名
或标号,则SEG A表示A所在段的段基值。
②格式: OFFSET 变量名或标号
返回变量或标号的偏移地址部分。例如,若A为变量名
或标号;则OFFSET A表示A的偏移地址部分。
③格式: TYPE 变量名或标号
返回变量或标号的类型属性值。
④格式: LENGTH 变量名
返回变量的长度,即以DUP形式表示的第一组变量被重
复设置的次数。
⑤ 格式: SIZE 变量名
返回变量的大小,即TYPE×LENGTH的值。也就是说,
SIZE=TYPE×LENGTH。
关于TYPE、LENGTH和SIZE的含义举例
对于“W1 DW 20 DUP(3, 10 DUP(7))”,则TYPE W1=2,
LENGTH W1=20,SIZE W1=40;
对于“W2 DW 8, 20 DUP(3, 10 DUP(7))”,则TYPE
W2=2,LENGTH W2=1, SIZE W2=2;
对于“B1 DB 20 DUP(3, 10 DUP(7))”,则TYPE B1=1,
LENGTH B1=
,SIZE B1=
;
对于“B2 DB 8, 20 DUP(3, 10 DUP(7))”,则TYPE
B2= ,LENGTH B2=
, SIZE B2=
。
(6) 指定属性(也称合成)伪操作
指定属性伪操作可用于指定存储器操作数或标号的属性,
常见的有PTR、:、THIS共3个符号,其功能分别为: 指
定存储器操作数或标号的类型、指定存储器操作数的段归
属、指定当地的变量或标号的类型。
① 格式: 类型名 PTR 存储器操作数或标号
例如,指令“MOV[BX], 5”的含义是将常数5送入存
储单元[BX]中 。该存储单元的偏移地址由BX确定,段
基值隐含为DS。但汇编程序无法确定常数5是字节还是字,
也无法确定存储单元[BX]的内容是字节还是字,所以无
法操作。
②格式: 段寄存器名 : 存储器操作数
临时指定存储器操作数的段归属。例如,“MOV AX, ES:
[BX]”表示该存储单元的段基值取自ES,而不是隐含
的DS。
③格式: THIS 类型名
临时指定当前地址处变量或标号的类型。例如,THIS
BYTE表示当前地址处变量的类型为字节,THIS FAR表示
当前地址处标号的类型为远。
THIS操作符会在当前段内产生一个偏移地址与$的值相等
的操作数,该操作数的类型由THIS右边的类型名确定。
THIS 可以像PTR一样建立一个指定类型(BYTE,WORD
或DWORD)或指定距离(NEAR或FAR)的操作数。该操
作数的段地址和偏移地址与下一个存储单元地址相同。
THIS 往往和伪指令说明符EQU 连用,为当前存储单元定
义一个指定类型的变量或标号,并为下一个能分配存储单
元的变量和标号定义新的类型。例如:
A EQU THIS BYTE
B DD 12345678H
就是将一个双字类型变量B临时指定为字节类型变量,它
与A 具有相同的段地址和偏移量。
例:
……….
A EQU THIS BYTE
B DD 12345678H
………...
CLD
MOV SI, OFFSET A
LODSB
…………
;AL
(DS:SI), SI
SI+1
DATA SEGMENT
A EQU THIS BYTE
B DD 12345678H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX,DATA
MOV DS,AX
CLD
MOV SI, OFFSET A
LODSB
;AL (DS:SI), SI
MOV AX,4C00H
INT 21H
CODE ENDS
END START
SI+1
又如:
START EQU THIS FAR
MOV CX ,100
这样,MOV 指令 有一个FAR 属性的地址START,这就允许
其他段的JMP 指令直接跳到START来。
(7) 分离操作符
有SHORT、HIGH和LOW三个,其功能是从其后的操作数
(或与其后的操作数有关的数据)中分离出一部分内容作为
返回值。
① 格式: SHORT 标号
只取出标号与IP之差(标号-IP)的低字节,即将标号按短
(距离)处理。
② 格式: HIGH 字操作数
从字操作数中分离出高字节。例如,HIGH 1234H的操作
结果为12H。
③ 格式: LOW 字操作数
从字操作数中分离出低字节。例如,LOW 1234H的操作
结果为34H。
4. 汇编语言的表达式
(1) 表达式及分类
用伪操作符将操作对象组合起来即得到表达式,单个操作
对象也可称为表达式。表达式可作为指令语句中的操作数
或伪指令语句中的参数。按操作性质的不同可将表达式分
为四类:
① 算术表达式
② 逻辑表达式
③ 关系表达式
④ 特殊表达式
(2) 表达式的操作顺序
表达式中常用的伪操作符按以下顺序依次优先处理:
① (i) ()、 []、〈〉(ii) LENGTH、WIDTH、SIZE、MASK
(iii) ·(结构字段名操作符)
(iv) : (段超越前缀的操作符)
(v) PTR、OFFSET、SEG、TYPE、THIS (vi) HIGH、LOW
② (i) + (正号)、- (负号)
(ii) *、/
(iii) MOD、SHL、SHR
(iv) +、 ③ EQ、NE、LT、LE、GT、GE
④ (i) NOT
(ii) AND
(iii) OR、XOR
⑤ SHORT
例如,因为“HIGH”运算优先于“+”运算,所以,
HIGH 1234H + 2 = 12H + 2 = 14H
HIGH (1234H + 2) = HIGH 1236H = 12H
7.1.5 汇编语言的伪指令说明符
1. 数据定义(存储单元分配)
数据定义说明符用于定义变量,也就是为变量分配存储单
元并可同时预置初始值,有DB、DW、DD、DF、DQ、
DT共6种说明符。
分别表示存储单元分配时以字节为单位、以字为单位、以
双字为单位、以3字(远字)为单位、以4字为单位、以10字
节为单位。
例如,在下述定义中,
A DB 12H, ?
B DW ?, 3456H
C DD 789ABCDEH
D DB ′A′, ′B′, ′C′, ′D′
E DB ′ABCD′
F DW ′AB′, ′CD′
上述各变量的存储情况如图7.4所示。显然,DB′AB′和
DW′AB′的存储情况不同。
A 12
?
B
?
?
56
34
C DE
BC
9A
78
D 41
42
43
44
图7.4 变量在存储器中的存储情况
E 41
42
43
44
F 42
41
44
43
程序例
DATA SEGMENT
TAB DW 1,2,3,4,5,6
ENTRY EQU 3
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
L: MOV AX, DATA
MOV DS, AX
MOV BX,OFFSET TAB
ADD BX, ENTRY
; MOV AX, TAB+3
MOV AX, [BX]
CODE ENDS
END L
上述程序执行后,AX=
2. 符号定义(表达式赋值)
有 =、EQU、PURGE共3种说明符,含义分别是被赋予、
被赋予、取消(释放)。
(1)格式: 符号名 = 表达式
将表达式的值赋予符号名,以后即可用该符号名代表此表
达式的值。
(2) 格式: 符号名 EQU 表达式或另一组标识符
将表达式的值或另一组标识符赋予符号名,以后即可用该
符号名代表此表达式的值或代替另一组标识符。
(3) 格式: PURGE 符号名1[,符号名2[,…… ]]
取消(释放)被EQU定义的符号名,以后即可用EQU对该符
号名再赋予不同的含义。
3. 段定义
段定义说明符共有3种,即SEGMENT、ENDS和
ASSUME,含义分别是段开始、段结束、指定段寄存器。
(1) 格式: 段名 SEGMENT[定位类型][组合类型][′类别′]
从段名代表的段基值开始定义一个段。其中的定位类型、组合类型和′
类别′一般都可省略,若不省略时各项的顺序不能变。
① 定位类型: 连接时用于指定该段应开始于什么样的物理地址。可
选择下列4种之一:
BYTE: 从当前可用的字节地址XXXX XXXX XXXX XXXX XXXX(任一地址)开始;
WORD: 从当前可用的字地址XXXX XXXX XXXX XXXX XXX0(偶数地址)开始;
PARA(缺省): 从当前可用的节地址XXXX XXXX XXXX XXXX 0000(16的倍数)开始;
PAGE: 从当前可用的页地址XXXX XXXX XXXX 0000 0000(256的倍数)开始。
其中,1节(paragraph) 为16字节,1页为16节即256字节。
② 组合类型: 连接时用于指定同名的各段之间的组合方式。
可选择下列6种之一:
PUBLIC
STACK
COMMON
MEMORY
AT表达式
NONE(缺省)
若省略组合类型或说明为NONE类型,则表示各个段不组
合,各有自己的段基值。
对堆栈段,必须用STACK类型说明,不能省略 。
③ ′类别′: 是要将组合后的各段按′类别′分类存放,同类别的
段将被相邻地放在一起。′类别′是由用户定义的、用一对
引号括起来的、长度不超过40个字符的名字(标识符)。
(2)格式: 段名 ENDS
表示该段到此结束。这里的段名必须与该段开始时
SEGMENT左边的段名相同。
(3) 格式: ASSUME 段寄存器名1:段名1[,段寄存器名2:
段名2[,…… ]]
该语句必须出现在有关的变量及标号使用之前,用于指定
某段(用段名标识)中的变量、标号等数据项由哪个段寄存
器寻址。
4. 指定段内的偏移地址
常用的有ORG和EVEN两种说明符,是指定下一个要用的
存储单元的偏移地址。
(1) 格式: ORG 常数表达式
指定当前可用的存储单元的偏移地址为常数表达式的值,
就是将常数表达式的值送入$。
(2) 格式: EVEN
将当前可用的存储单元的偏移地址调整为最近的偶数值,
就是将当前可用的最小偶数偏移地址值送入$。
例如,在下述伪指令语句序列中,
ORG 1000H
A DB 47H, 12H, 45H
EVEN
B DB 47H
ORG 1000H 将A的偏移地址部分指定为1000H,从A开始
存放3个字节变量,占用地址1000H、1001H和1002H,B的
偏移地址部分本应是1003H,但EVEN指令会将B的偏移地址
部分调整为偶数地址1004H。
对于字数组,为保证其从偶地址开始,可在它前面用
EVEN 伪操作来达到这一目的,形如:
DATA-SEG SEGMENT
EVEN
WORD-ARRAY DW 100 DUP(?)
DATA-SEG ENDS
5. 过程定义
有PROC、ENDP两种说明符,含义分别是过程开始与过
程结束,必须成对出现。
(1)格式: 过程名 PROC 类型属性名
从过程名代表的地址开始定义一个过程,其中的类型属性
名可选择NEAR或FAR两种之一,前者表示该过程为近过
程,后者表示该过程为远过程。
如果不给出类型属性名或给出NEAR,则视为近过程。
(2)格式: 过程名 ENDP
表示该过程到此结束。这里的过程名必须与过程开始时
PROC左边的过程名相同。
过程(子程序)的基本结构
Proc-A
过程名
Proc-A
PROC
NEAR(或FAR)
____________
____________
.
.
.
____________
RET
ENDP
6. 类型定义
类型定义说明符只有一个,即LABEL,可用来给当前地址
处的变量或标号取一个别名,并赋予另一种类型属性。
格式: 变量名或标号 LABEL 类型属性名
“LABEL”和“EQU THIS”的作用类似
7.宏定义、宏调用和宏扩展
宏(MACRO)是源程序中一段有独立功能的程序代码、它
只需在源程序中定义一次,就可以多次用一条宏指令来调
用它。
宏定义是用伪指令来实现的。其格式为:
Macro-name
MACRO
ּּּ
宏指令名
ENDM
[dummy Parameter List]
宏定义体
形式参数
(用逗号隔开)
其中MACRO和ENDM是一对伪指令说明符,这对伪指令之
间是宏定义体——一组有独立功能的程序代码
经宏定义定义后的宏指令就可以在源程序中调用,这种对
宏指令的调用称宏调用,宏调用的格式为:
Macro-name [actual parameter list](每一项之间用逗号隔开)
当源程序被汇编时,汇编程序将对每个宏调用作宏展开。
宏展开就是用宏定义体取代源程序中的宏指令名,而且用
实在参数一一取代宏定义的形式参数。
例1. 宏定义可以无变元
宏定义:SAVEREG MACRO 宏定义开始
PUSH AX
PUSH BX
宏指令
PUSH CX
PUSH DX 宏定义体
PUSH SI
PUSH DI
宏定义结束
ENDM
宏调用: SAVEREG
宏展开: 将宏定义体的内容(具有独立功能的代码段)全
部列出。
例2 宏定义带形式参数
宏定义: FOO
MACRO P1, P2, P3
MOV AX, P1
P2 P3
ENDM
宏调用: FOO WORD_VAR, INC, AX
宏展开: + MOV AX, WORD_VAR
+ INC AX
子程序调用和宏调用工作方式的区别
子程序调用工作方式:
主程序
子程序Q(x,y)
执行时调用
X←A,y←B
CALL Q
x←C,y←D
CALL Q
Q:
.
.
.
RET
宏调用工作方式:
主程序
汇编时展开
Q A,B
Q(A,B)
Q C,D
Q(C,D)
Q MACRO x,y
ENDM
子程序调用和宏调用工作方式的区别
1. 在处理时间上不同。
2. 用宏指令得到的目标代码长,占内存空间大,而且宏调用
的次数越多,所占内存空间越大;用子程序占内存空间
小,而且不会随调用次数的增加而增加,但执行时间长。
3. 传递参数的方式不同。
7.1.3 汇编语言程序的开发
汇编语言程序的建立及汇编过程
编辑程序
Edit.exe
Prog.asm
文件
汇编程序
Prog.obj
文件
Masm.exe
Prog.exe
文件
连接程序
Link.exe
汇编示意图
调用 MASM.EXE
.ASM
汇编
.OBJ
.LST
可选
.CRF
1.
汇编程序的主要功能
汇编程序分两种:
一种是基本汇编(ASM.EXE);
一种是宏汇编(MASM.EXE),宏汇编功能比较
强。
1.
检查源程序;
2.
测出源程序中的语法错误,并给出出错信息;
3.
产生目标文件(.OBJ),并可给出列表文件(同时列出汇
编语言源程序和机器语言目标程序的文件,称之为.LST文
件)和交叉索引文件(列出程序中使用的符号、变量和标
号以及引用情况,称之为.CRF文件)。
4.
展开宏指令。
2.
连接程序
汇编之后生成的OBJ文件必须经过链接过程,才能成为扩
展名.EXE的可执行文件。
链接的过程就是调用连接程序(LINK.EXE),对OBJ文
件进行定位、链接,最后生成扩展名为EXE的可执行文件。
如果需要,也可生成MAP文件和LIB文件。
连接示意图:
调用LINK.EXE
.OBJ
.OBJ
连接
.EXE
可选
.LIB
.MAP
.LIB
3.
调试程序(DEBUG.COM)
>DEBUG PROG.EXE
- U (反汇编)
- g =起始地址 断点地址
- T = 地址 指令条数
汇编语言程序开发中的相关文件
Handwritten source program
EDIT Editor program
MASM assembler program
PROG1.LST
PROG1.CRF
PROG1.OBJ
Libraries
LINK linker program
DEBUG debug program
Final debugged run module
Other
.OBJ files
BIOS和DOS中断
ROM BIOS(Basic Input Output System)——装于从地
址0FE00H开始的8k ROM中,提供了系统加电自检,引
导装入,主要I/O设备的处理程序及接口控制等功能模块。
使用BIOS功能调用,使程序员不必了解硬件I/O的具体接
口特性,可直接通过入口参数来调用,给编程带来方便。
调用格式:
设置入口参数;
设置功能号;
INT XXH;
例: MOV CX,0;
入口参数
MOV DX,0;
MOV AH,1; 功能号为1
INT 1AH;
DOS 中断(DOS 系统功能调用)
指类型为21H的软件中断,其对应的中断处理程序中包含
了一系列最常用的功能子程序,这些子程序分别实现外设
管理、文件读/写和管理、目录管理等功能。
例:在显示器上输出字符 $:
MOV DL, ’$’ ; (24H) 设置入口参数
MOV AH, 6 ;
设置功能号为6
INT 21H ;
DOS系统功能调用
第7章 作业
习题七
1题 ;5题; 9题 (1)(2);10题;11题