微机原理及应用
主讲:谢维成
http://xweicheng.ys168.com
scxweicheng@yahoo.com.cn
第 4章 汇编语言程序设计
? 汇编语言的格式
? 语句行的构成
? 指示性语句
? 指令语句
? 汇编语言程序设计及举例
4.1 汇编语言的格式 (P111、 P99<3>)
8086汇编语言程序举例
MY_DATA SEGMENT
SUM DB ?
MY_DATA ENDS
MY_CODE SEGMENT
ASSUME CS:MY_CODE,DS:MY_DATA
PORT_VAL EQU 3
MAIN PROC FAR
GO: PUSH DS
MOV AX,0
PUSH AX
MOV AX,MY_DATA
4.1 汇编语言的格式
MOV DS,AX
MOV SUM,0
CYCLE: CMP SUM,100
JNA NOT_DONE
MOV AL,SUM
OUT PORT_VAL,AL
HLT
NOT_DONE: IN AL,PORT_VAL
ADD SUM,AL
JMP CYCLE
4.1 汇编语言的格式
RET
MAIN ENDP
MY_CODE ENDS
END GO
1、汇编语言源程序是分段的,通常每个模块程
序包括数据段、堆栈段和若干代码段。
2、每个程序结构类似,可以复制。
4.2 语句行的构成
指令性语句,其格式为:
标号:(前缀)指令助记符 操作数;注释
GO: PUSH DS
指示性语句,又叫伪指令,其格式为:
变量 伪指令 操作数 ;注释
SUM DB ?
4.2 语句行的构成
4.2.1 标记 (P112)
机器语言 —用二进制数来表示指令和数据.
B0 64 什么意思?这就是机器语言。既不直观,
又不易理解和记忆.
MOV AL,64H ;大家很清楚,这就是助记符。
助记符 —反映指令的功能和主要特征,便于人
们理解和记忆。
返回
4.2 语句行的构成
指令除了操作码以外,还有一个操作数问题。
操作数可能放在存储器中,这就涉及一个地址问
题。程序中遇到转移指令或调用指令, 涉及地址转移,
若采用具体地址就不很方便, 一旦有错改动就很麻烦。
于是人们采用 标号 或 符号 来代替地址,例:
LP1: …
┇
LOOP LP1
汇编语言 —用助记符,符号地址以及标 号等 符 号
书写的程序。用汇编语言编写的程序叫 源程序 。
返回
4.2 语句行的构成
汇编: 汇编源程序需翻译成机器语言,变成可执
行文件,机器才能执行,这个翻译过程叫 汇编 。
汇编语言是面向具体计算机硬件的语言 ,和机器
密切相关。它最大缺点是可读性差,编程效率低。
高级语言 —编程时不需要对机器指令系统有深入了
解,稍加培训即可掌握。可读性强,功能强。
为什么要用汇编语言?汇编语言编写的程序 节省内
存,执行 速度 快 ,并为用户直接控制对象提供了手段。
故 实时性要求很高的程序多采用汇编语言程序 。
4.2 语句行的构成
操作码: 是一个助记符,它可以是指令、伪指令(又叫
伪操作)或宏指令。
操作数: 由寄存器、存储单元、数据项或其表达式构
成。汇编时一个表达式得到一个值。
注释: 用来说明程序或语句的功能, 用 分号; 作 为 注
释开始。
其中名字和注释视情况而定,可有可无.
4.2 语句行的构成
1、源程序
源程序 通常由一个或几个程序模块组成,每个模
块包括数据段、堆栈段和若干代码段。代 码段可有若
干个过程,过程中的语句分为两类:
指令性语句,其格式为:
标号: (前缀)指令助记符 操 作数;注释
指示性语句,又叫伪指令,其格式为:
变量 伪指令 操 作数 ;注释
4.2 语句行的构成
2、指令性语句
指令性语句 是计算机可执行的,而指示性语句不
能执行 ,用来定义变量,分配存储单元,指示程序开始
和结束等。
这两种语句的差别:
在形式上: 带不带冒号,是否可转向它.
在本质上:汇编时能否形成对应的机器码.
4.2.1 标记 - 4.2.2符号
数据项
数据项包括常量、变量、标号及表达式,下面分 别 加
以介绍。
1.常量
(1)数字常量
二进制常量,以 B结尾
十进制常量,以 D结尾或省略(汇编语言中默认无标
记数为十进制数)
十六进制常量,以 H结尾,如0A8C6H.
4.2.1 标记 - 4.2.2符号
(2)字符串常量
用引号引起来的字符或字符串也代表常数。
例 :’A’,’BCDE’,汇编时被翻译成对应的 ASCII码 41H和
42H,43H,44H,45H。
返回
4.2.1 标记 - 4.2.2符号
2.变量
变量是内存中的数据区 ,在程序中作为存储器操
作数来使用。如例子中BLOCK(在数据段中定义)
变量有三种属性:
①段 值 —变量定义所在段的段地址
②偏移量 —变量单元地址与段起始地址之
间的位移量。
③类 型 —有字节、字和双字三种。
4.2.1 标记 - 4.2.2符号
标号
标号 是某条指令所存放单元的符号地址,可作为转移指
令或CALL指令的转移地址。
标号也有三种属性:段值总是 在C S段 寄 存 器 中 ,偏移量
概念与变量同,类型分NEAR和FAR两种。
NEAR—表示标号所在语句与转移指令 或调 用指 令 在 同 一
码段内,只需改变IP即可。
FAR—标号所在语 句 与 转 移 指 令 或 调 用 指 令 不 在 同 一 码
段内。
若没有对类型进行说明,默认为NEAR。
4.2.3 表达式
4.表达式
表达式 是常数、寄存器、标号、变量与一些运
算符组合的序列 ,分数字表达式和地址表达式两种。
汇编时按一定的优先规则对表达式进行计 算 后 可 得
到一个数值或一个地址。
下面介绍五种运算符 :
4.2.3 表达式
(1)算术运算符
有+、-、*、/,以及M OD,其中M OD表示除法运
算后得到的余数。例:
19/7的商是2,19 MOD 7则为5(余数)
算术运算符可以用于数字表达式,例:
MOV AL,2*7 汇编后为B0,0E
算术运算符也可以用于地址表达式,对地址运算
的结果应有明确的物理意义, 例两个地址的乘或除无
意义,而加或减则可以,例:
LEA SI,SUM+3
表示 变量 SUM的地址加上3得到的和作为新存储
器地址。
4.2.3 表达式
(2)逻辑运算符
逻 辑 运 算 符 有 AND、OR、XOR 和 NOT, 它 们 只 能 用
于数字表达式中。
例:MOV CL,36H AND 0FH
经汇编后:MOV CL,06H
这些逻辑运算符也是8086/8088的指令助记符,会
不 会 造 成 混 乱 呢 ?不 会 的,前者在汇编时进行,而后者
在指令执行时进行的。
例:AND DX,PORT_VAR AND 0FEH
后一个逻辑运算符AND在汇编时进行, 若PORT_VAR
为81H,则汇编后表达式算出为8 0H.执行前一个指令助
记符AND时,将(DX)与80H相与,结果在DX中。
4.2.3 表达式
(3) 关系运算符
共有6个,它们为:
EQ(相等),NE(不等),LT(小于),GT(大于),
LE(小于或等于),GE(大于或等于)
关系运算符的两个操作数必须都是数字或者是同
一段内的两个存储器地址。
关系为真,结果为0FFFFH
关系为假,结果为0
例:MOV BX,PORT_VAL GE 5
若PORT_VAL的值大于等于5,则汇编后为:
MOV BX,0FFFFH
若PORT_VAL的值小于5, 则汇编后为:
MOV BX,0
4.2.3 表达式
(4)数值返回操作符
它可以把存储器一些特征作为数值送回。
这些操作符有OFFSET,SEG,TYPE,SIZE及LENGTH。
例:MOV SI,OFFSET STRI1 ;代表将变量
STRI1处的地址偏移量取到SI中.
注意与 MOV SI,STRI1的差别.
但它与 LEA SI,STRI1类似.
与此类似,SEG运算符用来取存储单元的段值,
例:
MOV AX,SEG STRI1 ;将变量STRI1所
MOV DS,AX ;在段值取到DS中
4.2.3 表达式
TYPE操作符
TYPE操作符用来取存储器的单元类型,各单元类
型对应值如下:
存储器单元类型 对应值
DB(字节) 1
DW(字) 2
DD(双字) 4
若BUFFER1存储区是用如下伪指令定义的:
BUFFER1 DB 100 DUP(?)
则 TYPE BUFFER1等于1
4.2.3 表达式
LENGTH操作符
LENGTH操作符用来计算一个存储区的单元(单元
可以是字节,字或双字)的数目。
注意LENGTH返回的存储区必须用复制操作符
DUP( )来定义,否则返回值为1。
例:
若FEES被定义为:FEES DW 4,5,6
则 MOV CX,LENGTH FEES
汇编后,MOV CX,1
操作符 SIZE用来计算一个存储区的 字节总数 。
4.2.3 表达式
三者关系
例:
若BUFFER2存储区是用如下伪指令定义的:
BUFFER2 DW 200 DUP(0)
则:
TYPE BUFFER2 等于2
LENGTH BUFFER2 等于200
SIZE BUFFER2 等于400
4.2.3 表达式
(5)类型操作符PTR
用来对存储单元规定类型,通常和伪指令
BYTE,WORD等连起来使用。
例:MOV BYTE PTR[DI],0
MOV WORD PTR[DI],0
而 MOV [DI],0 ;类型不定
PTR也可用来对已经规定了类型进行更改
4.2.3 表达式
例:STRI1 DW ? ; 定义为字类型
可用如下语句:
PP EQU BYTE PTR STRI1
QQ EQU BYTE PTR STRI1+1
通过PP,QQ把STRI1和STRI1+1又规定为字节类型。
MOV STRI1,AX 是合法的
MOV AL,STRI1 是非法的
只能用: MOV AL,PP
或 MOV AL,BYTE PTR STRI1
4.3 指示性语句(伪指令) (P120)
4.3 伪指令
常用的伪指令有:
符号赋值伪指令
变量定义伪指令
段定义伪指令
过程定义伪指令
结束伪指令
4.3.1 符号赋值伪指令
1.等值伪指令EQU
格式为:符号名 EQU 表达式
或:新符号名 EQU 老符号名
例: CONSTANTEQU 100
NEW_PORT EQU PORT_VAL+1
EQU伪指令在未解除前,不能重新定义。
4.3.1 符号赋值伪指令
2.等号(=)伪指令
与EQU类似,但允许重新定义
例: ┇
EMP=7 ;值为7
┇
EMP=EMP+1 ;值为8
4.3.1 符号赋值伪指令
3.解除伪指令PURGE
已用EQU定义的符号,可用PURGE解除,再重
新定义。
例:PURGE NEW_PORT
NEW_PORT EQU POTR_VAL+8
4.3.1 符号赋值伪指令
变量 是内存中数据区的名字,故这类伪
指令又可叫数据定义伪指令。这类伪指令格
式为:
变量名 伪指令助记符 操作数 ;注释
其中变量名用符号地址表示,后面不能跟
冒号,它可有可无。
4.3.2 数据定义语句 (P121)
伪指令助记符有如下几种:
DB 用来定义字节
DW 用来定义字
DD 用来定义双字
操作数可以是常数或表达式
注释用来说明伪指令的功能,它亦可有可无。
例1:DATA_BYTE DB 10,5,10H
DATA_WORD DW 100H,100,-4
DATA_DW DD 2*30,0FFFBH
4.3.2 数据定义语句
0A
05
10
00
01
64
00
FC
FF
3C
00
00
00
FB
FF
00
00
DATA_BYTE
DATA_DW
DATA_WORD
10
5
10H
100H
100
-4
60
0FFFBH
汇编后如图所示:
4.3.2 数据定义语句
例2:操作数可以是字符串
MASTERLI DB ‘HELLO’
汇编后如下:
48
45
4C
4C
4F
MASTERLI ‘H’
‘E’
‘L’
‘L’
‘O’
注意下面的不同:
DB’AB’ DW’AB’
41 ‘A’ 42 ‘B’
42 ‘B’ 41 ‘A’
4.3.2 数据定义语句
操作数 ?用来保留存储空间,但不存入数据.
例3: ABC DB 0,1,?,?,?
LPI DW ?,54,?
汇编后如下图示:
00
01
╳
╳
╳
╳
╳
36
00
╳
╳
ABC
LPI
0
1
?
?
?
?
?
54
4.3.2 数据定义语句
操作数字段还可以用复制操作符 DUP来 缩 写,如上面
ABC亦可写成:
ABC DB 0,1,3 DUP(?)
又如: DO-2 DB 2 DUP(0,1,2,?)
与 DO-2 DB 0,1,2,?,0,1,2,?等价
在伪操作的操作数字段中若使用$,则表示的是地
址计数器的当前值。
4.3.2 数据定义语句
? 例: BUFFER DW 3,4,$+3
? 设BUFFER的偏移地址为0088H,则汇编后如下图所示:
03
00
04
00
8F
00
BUFFER 0088H
008CH+3
返回
4.3.3 段定义语句 (P127)
段定义伪指令
因8086/8088 C PU的存储器是分段的,这就需要
有段定义语句。
与段有关的伪指令有:
SEGMENT、ENDS、ASSUME、ORG
段定义伪指令的格式如下:
段名 SEGMENT
┇
段名 ENDS
返回
4.3.3 段定义语句
SEGMENT、ENDS
这两 个伪 指令总是成对出现,二者前面的段名
一致。二者之间的删节部分,对数据段、 附 加 段 及
堆栈段,一般是符号、变量定义等伪指令 。 对 于 代
码段则是指令及伪指令。
此外,还必须 明确段和段寄存器 的关系,这可
由ASSUME语句来实现。其格式为:
ASSUME Seg-reg:SEGNAME [,…]
其 中 段 寄 存 器 名 必 须 是 CS、DS、ES 或 SS中 的 一
个,而段名则是由SEGMENT及ENDS定义的段名。
返回
4.3.3 段定义语句
ASSUME
需指出的一点,A SSUME伪指令只是告知汇编程序
有关段寄存器与段的关系, 并没有给段寄存器赋予实
际的初值。故例中
MOV AX,DATA
MOV DS,AX
MOV ES,AX
如程 序中 用到堆栈段,也需装入实际的初值。
而代码段不需要用户装,由初始化程序装入。
返回
4.3.3 段定义语句 (P127)
伪指令ORG
伪指令O RG规定了段内的起始地址或偏移地址,
其格式为:
ORG <表达式>
表达 式的 值即为段内的起始地址或偏移地址,
从此地址起连续存放程序或数据。
返回
4.3.4 过程定义语句 (P131)
PROC、ENDS、CALL、RET
过程定义格式为:
PROC、ENDS、CALL、RET
段定义伪指令的格式如下:
过程名 PROC
┇
RET
过程名 ENDP
返回
4.4 指令性语句 (P132)
指令?
返回