第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院教学重点第 2章学习了 8086硬指令,
第 3章介绍 MASM基本的伪指令 。 第 3章重点掌握:
程序的格式,开发方法
参数的表达,变量的定义
变量和标号的属性第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院硬指令和伪指令
硬指令 —— 使 CPU产生动作,并在程序执行时才处理的语句,就是第 2章学习的处理器指令
伪指令 ( Directive) —— 不产生 CPU动作,
在程序执行前由汇编程序处理的说明性语句,
例如,数据说明,变量定义等等
伪指令与具体的处理器类型无关,但与汇编程序的版本有关本课程采用微软宏汇编程序 MASM 6.15
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.1 汇编语言程序的开发
本节从汇编语言程序的 语句格式 出发,
给出第一个示范性的汇编语言 源程序,
并演示汇编语言程序的过程:
编辑 汇编 连接 调试
即汇编语言程序的开发方法第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.1.1 汇编语言程序的语句格式
⑴ 执行性语句 —— 由硬指令构成的语句,
它通常对应一条机器指令,出现在程序的代码段中:
标号,硬指令助记符 操作数,操作数 ;注释
⑵ 说明性语句 —— 由伪指令构成的语句,
它通常指示汇编程序如何汇编源程序:
名字 伪指令助记符 参数,参数,… ;注释
MOV CX,0 ;传送指令,具有 2个操作数
DELAY:NOP;空操作指令,没有操作数,带有标号
LOOP DELAY;循环指令,标号 DELAY说明转移位置
BUFFERDB 1,2,3,4,5,6,7;数据定义伪指令,在主存中开辟 7个连续的字节单元,初值依次为 1~ 7,BUFFER表示首地址第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院标号、名字与标识符
标号 是反映硬指令位置 ( 逻辑地址 ) 的标识符,
后跟一个冒号分隔
名字 是反映伪指令位置 ( 逻辑地址 ) 和属性的标识符,后跟空格或制表符分隔,没有一个冒号
标识符 ( Identifier) 一般最多由 31个字母,数字及规定的特殊符号 ( 如 _,$,?,@) 组成,不能以数字开头 。 默认情况下,汇编程序不区别标识符中的字母大小写
一个程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院保留字
保留字 ( Reserved Word) 是汇编程序已经利用的标识符,主要有:
o硬指令助记符 —— 例如,MOV,ADD
o伪指令助记符 —— 例如,DB,EQU
o操作符 —— 例如,OFFSET,PTR
o寄存器名 —— 例如,AX,CS
o预定义符号 —— 例如,@data
汇编语言大小写不敏感第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院助记符
硬指令助记符 可以是任何一条处理器指令,也可以是一条宏指令
伪指令助记符 将在本章和下章学习
前一章引入的定义字节数据和字符串的
DB就是伪指令第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院操作数与参数
处理器指令的 操作数 可以是立即数,寄存器和存储单元
伪指令的 参数 可以是常数,变量名,表达式等,可以有多个,
参数之间用逗号分隔第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院注释
语句中由分号,;,开始的部分为注释内容,用以增加源程序的可读性
必要时,一个语句行也可以由分号开始作为阶段性注释
汇编程序在翻译源程序时将跳过该部分,
不对它们做任何处理第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院分隔符
语句的 4个组成部分要用分隔符分开
标号后用冒号,注释前用分号
操作数之间和参数之间使用逗号分隔
其他部分通常采用空格或制表符
多个空格和制表符的作用与一个相同
MASM支持续行符,\”
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.1.2 汇编语言的程序格式
完整的汇编语言源程序由段组成
一个汇编语言源程序可以包含若干个代码段,
数据段,附加段或堆栈段,段与段之间的顺序可随意排列
需独立运行的程序必须包含一个代码段,并指示程序执行的起始点,一个程序只有一个起始点
所有的可执行性语句必须位于某一个代码段内,说明性语句可根据需要位于任一段内
通常,程序还需要一个堆栈段第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院汇编语言源程序
源程序分别用两种格式书写
第一种格式从 MASM 5.0开始支持
简化段定义格式
第二种格式 MASM 5.0以前就具有
完整段定义格式
Hello,Everybody !
程序功能;lt301a.asm( 文件名 )
.model small ;定义程序的存储模式
.stack ;定义堆栈段
.data ;定义数据段
string db ’Hello,Everybody !’,0dh,0ah,’$’;在数据段定义要显示的字符串
.code ;定义代码段
.startup ;程序起始点,建立 DS,SS
mov dx,offset string ;指定字符串
mov ah,9
int 21h ;利用功能调用显示信息
.exit 0 ;程序结束点,返回 DOS
end ;汇编结束;SampleA.ASM
.model small
.stack
.data
..,;在数据段定义数据
.code
.startup
..,;在代码段填入指令序列
.exit 0
..,;子程序代码
end
简化段定义格式
MASM 6.x支持
3.1.3 汇编语言程序的开发过程编辑文本编辑器,如 EDIT.COM
源程序:文件名,asm
汇编汇编程序,如 ML.EXE
目标模块:文件名,obj
连接连接程序,如 LINK.EXE
可执行文件:文件名,exe
调试调试程序,如 CodeView
应用程序 错误错误错误错误开发过程 1:源程序的编辑源程序文件要以 ASM为扩展名源程序文件的形成 ( 编辑 ) 可以通过任何一个文本编辑器实现,
DOS中的全屏幕文本编辑器 EDIT
其他程序开发工具中的编辑环境
MASM程序员工作平台 PWB中的编辑环境
EDIT lt301a.asm
开发过程 2:源程序的汇编汇编是将源程序翻译成由机器代码组成的目标模块文件的过程
MASM 6.x提供的汇编程序是 ML.EXE:
ML /c lt301a.asm
如果源程序中没有语法错误,MASM将自动生成一个目标模块文件 ( lt301a.obj) ;
否则 MASM将给出相应的错误信息这时应根据错误信息,重新编辑修改源程序后,再进行汇编开发过程 3:目标模块的连接连接程序能把一个或多个目标文件和库文件合成一个可执行程序 (,EXE,.COM文件 ),
LINK lt301a.obj
如果没有严重错误,LINK将生成一个可执行文件 ( lt301a.exe) ;否则将提示相应的错误信息这时需要根据错误信息重新修改源程序后再汇编,链接,直到生成可执行文件汇编和连接过程可以依次自动完成汇编和连接的依次自动实现
ML汇编程序可自动调用 LINK连接程序,
实现汇编和连接的依次进行
ML lt301a.asm
汇编程序 ML.EXE可带其他参数,常用
ML /Fl /Sg lt301a.asm
该命令除产生模块文件 lt301a.obj和可执行文件 lt301a.exe外,还将生成列表文件 lt301a.lst
列表文件是一种文本文件,含有源程序和目标代码,对我们学习汇编语言程序设计和发现错误很有用 。 采用 /Sg选项,将在列表文件中得到有些伪指令相应的硬指令开发过程 4:可执行程序的调试经汇编,连接生成的可执行程序在操作系统下只要输入文件名就可以运行:
lt301a
操作系统装载该文件进入主存,并开始运行如果出现运行错误,可以从源程序开始排错,也可以利用调试程序帮助发现错误第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2 参数、变量和标号
本节详细讨论汇编语言程序语句的主要部分:
参数 变量名 标号
并引出相关的伪指令和操作符
本节重点掌握:
常数的表达,
变量定义伪指令 DB/DW/DD、
地址操作符和类型操作符第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2.1 数值型参数
在源程序语句格式的 4个组成部分中,
参数是指令的操作对象 ( 学习硬指令时被称为操作数 ),参数之间用逗号分隔
参数根据指令不同可以没有,可以有 1
个,2个或多个
汇编语言程序中,指令参数有数值型,
它的主要形式是常数和数值表达式;
硬指令的操作数有立即数;立即数就要用数值型参数表达第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
1,常数
常数 ( 常量 ) 表示一个固定的数值
它又分成多种形式:
( 1) 十进制常数
( 2) 十六进制常数
( 3) 二进制常数
( 4) 八进制常数
( 5) 字符串常数
( 6) 符号常数第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
2,数值表达式
数值表达式一般是指由运算符连接的各种常数所构成的表达式
汇编程序在汇编过程中计算表达式,最终得到一个数值
程序运行之前,就已经计算出了表达式;所以,程序运行速度没有变慢,但增强程序的可读性
MASM对除伪指令外各种汇编时处理的指令统称为操作符 ( Operator)
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院地址型参数
汇编语言程序中,指令参数还有地址型,
它的主要形式是标号和名字 ( 变量名,段名,过程名等 )
硬指令的操作数有存储单元;存储单元就应该用地址型参数 ( 存储器操作数 ) 表达第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2.2 变量定义伪指令
变量定义 ( Define) 伪指令为变量申请固定长度的存储空间,并可同时将相应的存储单元初始化变量名 伪指令助记符 初值表变量定义伪指令最常使用第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院变量名
变量名为用户自定义标识符,表示初值表首元素的逻辑地址 ;用这个符号表示地址,常称为符号地址
变量名可以没有 。 这种情况,汇编程序将直接为初值表分配空间,无符号地址
设置变量名是为了方便存取它指示的存储单元第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院初值表
初值表是用逗号分隔的参数
主要由数值常数,表达式或?,DUP
组成
? —— 表示初值不确定,即未赋初值;
DUP—— 表示重复初值
DUP的格式为:
重复次数 DUP(重复参数 )
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院变量定义伪指令助记符
变量定义伪指令根据申请的主存空间单位分类
DB—— 定义字节伪指令
DW—— 定义字伪指令
DD—— 定义双字伪指令
DF—— 定义 3字伪指令
DQ—— 定义 4字伪指令
DT—— 定义 10字节伪指令
还有定位伪指令定义字节单元伪指令 DB
DB伪指令用于分配一个或多个字节单元,
并可以将它们初始化为指定值初 值 表 中 每 个 数 据 一 定 是 字 节 量
( Byte),存放一个 8位数据:
可以是 0~255的无符号数或是- 128~+ 127带符号数也可以是字符串常数
data segment ;数据段
X db 'a',-5
db 2 dup(100),?
Y db 'ABC'
data ends
mov al,X;此处 X表示它的第 1个数据,故 AL←'a'
dec X+1;对 X为始的第 2个数据减 1,故成为 -6
mov Y,al;现在 Y这个字符串成为 'aBC'
定义字单元伪指令 DW
DW伪指令用于分配一个或多个字单元,并可以将它们初始化为指定值初 值 表 中 每 个 数 据 一 定 是 字 量
( Word),一个字单元可用于存放任何 16位数据:
一个段地址一个偏移地址两个字符
0~ 65535之间的无符号数
- 32768~+ 32767之间的带符号数
data segment ;数据段
count dw 8000h,?,'AB'
maxintequ 64h
numberdw maxint
array dw maxint dup(0)
data ends
字变量和字常量的定义:
WNUM EQU 5678H ;定义 WNUM为常量
COUNTDW 20H;定义 COUNT变量,假设在数据段的偏移地址为 10H
字变量和字常量的应用:
MOV AX,[BX+SI+WNUM] ; MOV AX,[BX+SI+5678H]
MOV AX,COUNT ; MOV AX,[0010H]
MOV AX,[SI+COUNT] ; MOV AX,COUNT[SI]; MOV AX,[SI+10H]
LEA BX,COUNT ; LEA BX,[0010H]
MOV BX,OFFSET COUNT ; MOV BX,0010H
定义双字单元伪指令 DD
DD伪指令 用于分配一个或多个双字单元,
并可以将它们初始化为指定值初值表中每个数据是一个 32位的双字量
( Double Word),
可以是有符号或无符号的 32位整数也可以用来表达 16位段地址 ( 高位字 ) 和
16位的偏移地址 ( 低位字 ) 的远指针
vardd DD 0,?,12345678h
farpoint DD 00400078h
例 3.2,数据定义综合应用- 1/2
.model small
.stack
.data
bvar DB 16
wvar DW 4*3
dvar DD 4294967295 ;= 232- 1
qvar DQ?
DB 1,2,3,4,5
tvar DT 2345 ;定义了 BCD码 2345H
abc DB 'a','b','c'
msg DB 'Hello',13,10,'$'
bbuf DB 12 DUP('month')
dbuf DD 25 DUP(?)
CALLDOS EQU <int 21h>
例 3.2,数据定义综合应用- 2/2
.code
.startup
mov bl,bvar
mov ax,word ptr dvar[0]
mov dx,word ptr dvar[2] ;取双字到 DX.AX
mov dx,offset msg
mov ah,09h
CALLDOS
.exit 0
end
例 3.3,数据复制和显示- 1/2
.model small
.stack
.data
source db 33h,34h,35h,36h ;定义 4个字符数据
target db 80 dup(?) ;分配数据空间 4× 20=80
.code
.startup
mov ax,ds
mov es,ax ;data也作为附加段
cld
mov si,offset source
mov di,offset target
mov cx,80
例 3.3,数据复制和显示- 2/2
rep movsb ;串传送
mov si,0 ;显示
mov bx,offset target
again,mov dl,[bx+si]
mov ah,2
int 21h
inc si
cmp si,80
jb again
.exit 0
end
定位伪指令定位伪指令控制数据的偏移地址
ORG 参数
ORG伪指令是将当前偏移地址指针指向参数表达的偏移地址:
ORG 100h ;从 100h处安排数据或程序
ORG $+10;使偏移地址加 10,即跳过 10个字节空间
MASM中,符号,$”表示当前偏移地址值第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2.3 变量和标号的属性
① 地址属性
标号和名字对应存储单元的逻辑地址
逻辑地址包括:段地址和偏移地址
② 类型属性
标号,子程序名的类型可以是 NEAR
( 近 ) 和 FAR( 远 ),分别表示段内或段间
变量名的类型可以是 BYTE( 字节 ),
WORD( 字 ) 和 DWORD( 双字 ) 等地址操作符
取得名字或标号的段地址和偏移地址两个属性
[ ] 将括起的表达式作为存储器地址
$ 当前偏移地址
,采用指定的段地址寄存器
OFFSET 名字 /标号返回名字或标号的偏移地址
SEG 名字 /标号返回名字或标号的段地址
org $+10
array db 45,45h
.code
mov ax,seg array
mov ds,ax
mov bx,offset array;等价于 lea bx,array
mov cl,array+4;等效于 mov cl,array[4]
mov ax,es:[2000h]
加 4个字节单元类型操作符
类型操作符对名字或标号的类型属性进行有关设置类型名 PTR 名字 /标号
THIS 类型名
SHORT 标号
TYPE 名字 /标号
SIZEOF 变量名
LENGTHOF 变量名
PTR操作符类型名 PTR 名字 /标号
PTR操作符使名字或标号具有指定的类型
类型名可以是
BYTE/WORD/DWORD/FWORD/QWORD/TBYTE
或者是 NEAR/FAR,还可以是由 STRUCT,RECORD、
UNION以及 TYPEDEF定义的类型
mov al,byte ptr w_var ;w_var是一个字变量
jmp far ptr n_label ;n_label是一个标号
使用 PTR操作符,可以临时改变名字或标号的类型
THIS操作符
THIS 类型名
利用 THIS说明的操作数具有汇编时的当前逻辑地址,
但具有指定的类型
b_var equ THIS byte;按字节访问变量 b_var,但与 w_var的地址相同
w_var dw 10 dup(0) ;按字访问变量 w_var
f_jump equ THIS far;用 f_jump为段间转移 ( f_jump label far)
n_jump,mov ax,w_var;用 n_jump为段内近转移,但两者指向同一条指令
LABEL伪指令的功能等同于,EQU THIS”
TYPE操作符
TYPE 名字 /标名
返回表明名字或标号类型的一个字量数值
对字节,字和双字变量依次返回 1,2和 4;
对短,近和远转移依次返回 ff01h,ff02h和 ff05h
mov ax,TYPE w_var ;汇编结果为 mov ax,2
mov ax,TYPE n_jump;汇编结果为 mov ax,0ff02h( near标号 )
操作符 SIZEOF返回整个变量占用的字节数
LENGTHOF返回整个变量的数据项数 ( 即元素数 )
SIZEOF = LENGTHOF × TYPE
.model small
.stack
.data
v_byte equ this byte;v_byte是字节类型,与变量 v_word的地址相同
v_word dw 3332h,3735h;v_word是字类型的变量
target dw 5 dup(20h);分配数据空间 2× 5= 10字节
crlf db 0dh,0ah,'$'
flag db 0
n_point dw offset s_label;取得标号 s_label的偏移地址例 3.4:属性及其 应用- 1/5
例 3.4:属性及其 应用- 2/5
.code
.startup
mov al,byte ptr v_word;用 PTR改变 v_word的类型,否则类型不匹配
dec al
mov v_byte,al;对 v_word的头一个字节操作,原为 32H,现为 31H
n_label,cmp flag,1
jz s_label ;flag单元为 1转移
inc flag
jmp n_label ;进行短转移例 3.4:属性及其 应用- 3/5
s_label,cmp flag,2
jz next ;flag单元为 2转移
inc flag
jmp n_point;段内的存储器间接寻址,转移到 s_label标号处
next,mov ax,type v_word;汇编结果为 mov ax,2
mov cx,lengthof target;汇编结果为 mov cx,5
例 3.4:属性及其 应用- 4/5
mov si,offset target
w_again,mov [si],ax ;对字单元操作
inc si ;SI指针加 2
inc si
loop w_again ;循环
mov cx,sizeof target;汇编结果为 mov cx,0ah
mov al,'?'
mov di,offset target
b_again,mov [di],al ;对字节单元操作
inc di ;DI指针加 1
loop b_again ;循环例 3.4:属性及其 应用- 5/5
mov dx,offset v_word;显示结果,1357
mov ah,9
int 21h
.exit 0
end
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.3 程序段的定义和属性
详述汇编语言程序格式的组成部分首先,简单了解 DOS支持的 exe程序和
com程序其次,重点掌握简化段定义格式的各条伪指令最后,理解完整段定义格式所包含的各种段属性
exe程序
利用程序开发工具,通常将生成 EXE结构的可执行程序 ( 扩展名为,EXE的文件 )
它可以有独立的代码,数据和堆栈段,还可以有多个代码段或多个数据段,程序长度可以超过
64KB,执行起始处可以任意指定
当 DOS装入或执行一个程序时,DOS确定当时主存最低的可用地址作为该程序的装入起始点 。 此点以下的区域称为程序段 。 在程序段内偏移 0处,
DOS为该程序建立一个程序段前缀控制块 PSP
( Program Segment Prefix),它占 256( =100h)
个字节;而在偏移 100h处才装入程序本身
com程序
COM程序是一种将代码,数据和堆栈段合一的结构紧凑的程序,所有代码,数据都在一个逻辑段内,不超过 64KB
在程序开发时,需要满足一定要求并采用相应参数才能正确生成 COM结构的程序
COM文件存储在磁盘上是主存的完全影象,不包含重新定位的加载信息,与 EXE文件相比其加载速度更快,占用的磁盘空间也少
尽管 DOS也为 COM程序建立程序段前缀 PSP,但由于两种文件结构不同,所以加载到主存后各段设置并不完全一样;SampleA.ASM
.model small
.stack
.data
..,;在数据段定义数据
.code
.startup
..,;在代码段填入指令序列
.exit 0
..,;子程序代码
end
简化段定义格式
MASM 6.x支持存储模式伪指令
.MODEL 存储模式
使用简化段定义,必须有存储模式伪指令
,model语句必须位于所有段定义语句之前
存储模式决定一个程序的规模,确定进行子程序调用,指令转移和数据访问的缺省属性
MASM有 7种不同的存储模式:
① TINY ② SMALL
③ COMPACT ④ MEDIUM
⑤ LARGE ⑥ HUGE
⑦ FLAT
简化段定义伪指令
.STACK [大小 ] ;堆栈段开始
.DATA ;数据段开始
.CODE [段名 ] ;代码段开始
简化段定义伪指令指明一个逻辑段的开始,同时自动结束前面的一个段采用简化段定义伪指令前,需有,model语句
使用简化段定义,各段名称和其他用户所需的信息可以使用 MASM预定义符号,例如:
@data表示由,data等定义的数据段的段名程序开始伪指令.STARTUP
按照 CPU类型,存储模式,操作系统和堆栈类型,产生程序开始执行的代码;同时还指定程序开始执行的起始点
在 DOS下,还将设置
DS值,调整 SS和 SP值
mov dx,dgroup
mov ds,dx ;设置 DS
mov bx,ss
sub bx,dx
shl bx,1
shl bx,1
shl bx,1
shl bx,1
cli ;关中断
mov ss,dx ;调整 SS和 SP
add sp,bx
sti ;开中断
mov dx,@data
mov ds,dx
程序终止伪指令
.EXIT [返回参数 ]
产生终止程序执行返回操作系统的指令代码
它的可选参数是一个返回的数码,通常用 0
表示没有错误 。 例如,exit 0对应的代码是:
mov ax,4c00h
int 21h
DOS功能调用的 4ch子功能 ( 返回 DOS),
入口参数,AH= 4ch,AL=返回数码汇编结束伪指令
END [标号 ]
指示汇编程序 MASM到此结束汇编过程
源程序的最后必须有一条 END语句
可选的标号用于指定程序开始执行点,连接程序将据此设置 CS,IP值
采用了,startup伪指令就不需要再用,end
标号,指明开始执行点,但还要有 end伪指令
———— 不要糊涂 ————
程序终止和汇编结束是两码事
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院第 3章 教学要求 ( 1)
1,掌握汇编语言语句格式
2,掌握简化段定义源程序格式
3,掌握常量表达,变量定义及应用,变量,标号和逻辑段的属性
4,了解数值表达式和 DOS的程序结构
5,掌握汇编语言源程序的编辑,汇编,连接和调试的开发方法
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院第 3章 教学要求 ( 2)
6,掌握基本伪指令和操作符:
EQU/=,+- */,DB/ DW/ DD,? / DUP
ORG/ $,OFFSET/ SEG/ PTR
.MODEL/,STACK/,DATA/,CODE/ END
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院教学重点第 2章学习了 8086硬指令,
第 3章介绍 MASM基本的伪指令 。 第 3章重点掌握:
程序的格式,开发方法
参数的表达,变量的定义
变量和标号的属性第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院硬指令和伪指令
硬指令 —— 使 CPU产生动作,并在程序执行时才处理的语句,就是第 2章学习的处理器指令
伪指令 ( Directive) —— 不产生 CPU动作,
在程序执行前由汇编程序处理的说明性语句,
例如,数据说明,变量定义等等
伪指令与具体的处理器类型无关,但与汇编程序的版本有关本课程采用微软宏汇编程序 MASM 6.15
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.1 汇编语言程序的开发
本节从汇编语言程序的 语句格式 出发,
给出第一个示范性的汇编语言 源程序,
并演示汇编语言程序的过程:
编辑 汇编 连接 调试
即汇编语言程序的开发方法第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.1.1 汇编语言程序的语句格式
⑴ 执行性语句 —— 由硬指令构成的语句,
它通常对应一条机器指令,出现在程序的代码段中:
标号,硬指令助记符 操作数,操作数 ;注释
⑵ 说明性语句 —— 由伪指令构成的语句,
它通常指示汇编程序如何汇编源程序:
名字 伪指令助记符 参数,参数,… ;注释
MOV CX,0 ;传送指令,具有 2个操作数
DELAY:NOP;空操作指令,没有操作数,带有标号
LOOP DELAY;循环指令,标号 DELAY说明转移位置
BUFFERDB 1,2,3,4,5,6,7;数据定义伪指令,在主存中开辟 7个连续的字节单元,初值依次为 1~ 7,BUFFER表示首地址第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院标号、名字与标识符
标号 是反映硬指令位置 ( 逻辑地址 ) 的标识符,
后跟一个冒号分隔
名字 是反映伪指令位置 ( 逻辑地址 ) 和属性的标识符,后跟空格或制表符分隔,没有一个冒号
标识符 ( Identifier) 一般最多由 31个字母,数字及规定的特殊符号 ( 如 _,$,?,@) 组成,不能以数字开头 。 默认情况下,汇编程序不区别标识符中的字母大小写
一个程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院保留字
保留字 ( Reserved Word) 是汇编程序已经利用的标识符,主要有:
o硬指令助记符 —— 例如,MOV,ADD
o伪指令助记符 —— 例如,DB,EQU
o操作符 —— 例如,OFFSET,PTR
o寄存器名 —— 例如,AX,CS
o预定义符号 —— 例如,@data
汇编语言大小写不敏感第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院助记符
硬指令助记符 可以是任何一条处理器指令,也可以是一条宏指令
伪指令助记符 将在本章和下章学习
前一章引入的定义字节数据和字符串的
DB就是伪指令第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院操作数与参数
处理器指令的 操作数 可以是立即数,寄存器和存储单元
伪指令的 参数 可以是常数,变量名,表达式等,可以有多个,
参数之间用逗号分隔第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院注释
语句中由分号,;,开始的部分为注释内容,用以增加源程序的可读性
必要时,一个语句行也可以由分号开始作为阶段性注释
汇编程序在翻译源程序时将跳过该部分,
不对它们做任何处理第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院分隔符
语句的 4个组成部分要用分隔符分开
标号后用冒号,注释前用分号
操作数之间和参数之间使用逗号分隔
其他部分通常采用空格或制表符
多个空格和制表符的作用与一个相同
MASM支持续行符,\”
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.1.2 汇编语言的程序格式
完整的汇编语言源程序由段组成
一个汇编语言源程序可以包含若干个代码段,
数据段,附加段或堆栈段,段与段之间的顺序可随意排列
需独立运行的程序必须包含一个代码段,并指示程序执行的起始点,一个程序只有一个起始点
所有的可执行性语句必须位于某一个代码段内,说明性语句可根据需要位于任一段内
通常,程序还需要一个堆栈段第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院汇编语言源程序
源程序分别用两种格式书写
第一种格式从 MASM 5.0开始支持
简化段定义格式
第二种格式 MASM 5.0以前就具有
完整段定义格式
Hello,Everybody !
程序功能;lt301a.asm( 文件名 )
.model small ;定义程序的存储模式
.stack ;定义堆栈段
.data ;定义数据段
string db ’Hello,Everybody !’,0dh,0ah,’$’;在数据段定义要显示的字符串
.code ;定义代码段
.startup ;程序起始点,建立 DS,SS
mov dx,offset string ;指定字符串
mov ah,9
int 21h ;利用功能调用显示信息
.exit 0 ;程序结束点,返回 DOS
end ;汇编结束;SampleA.ASM
.model small
.stack
.data
..,;在数据段定义数据
.code
.startup
..,;在代码段填入指令序列
.exit 0
..,;子程序代码
end
简化段定义格式
MASM 6.x支持
3.1.3 汇编语言程序的开发过程编辑文本编辑器,如 EDIT.COM
源程序:文件名,asm
汇编汇编程序,如 ML.EXE
目标模块:文件名,obj
连接连接程序,如 LINK.EXE
可执行文件:文件名,exe
调试调试程序,如 CodeView
应用程序 错误错误错误错误开发过程 1:源程序的编辑源程序文件要以 ASM为扩展名源程序文件的形成 ( 编辑 ) 可以通过任何一个文本编辑器实现,
DOS中的全屏幕文本编辑器 EDIT
其他程序开发工具中的编辑环境
MASM程序员工作平台 PWB中的编辑环境
EDIT lt301a.asm
开发过程 2:源程序的汇编汇编是将源程序翻译成由机器代码组成的目标模块文件的过程
MASM 6.x提供的汇编程序是 ML.EXE:
ML /c lt301a.asm
如果源程序中没有语法错误,MASM将自动生成一个目标模块文件 ( lt301a.obj) ;
否则 MASM将给出相应的错误信息这时应根据错误信息,重新编辑修改源程序后,再进行汇编开发过程 3:目标模块的连接连接程序能把一个或多个目标文件和库文件合成一个可执行程序 (,EXE,.COM文件 ),
LINK lt301a.obj
如果没有严重错误,LINK将生成一个可执行文件 ( lt301a.exe) ;否则将提示相应的错误信息这时需要根据错误信息重新修改源程序后再汇编,链接,直到生成可执行文件汇编和连接过程可以依次自动完成汇编和连接的依次自动实现
ML汇编程序可自动调用 LINK连接程序,
实现汇编和连接的依次进行
ML lt301a.asm
汇编程序 ML.EXE可带其他参数,常用
ML /Fl /Sg lt301a.asm
该命令除产生模块文件 lt301a.obj和可执行文件 lt301a.exe外,还将生成列表文件 lt301a.lst
列表文件是一种文本文件,含有源程序和目标代码,对我们学习汇编语言程序设计和发现错误很有用 。 采用 /Sg选项,将在列表文件中得到有些伪指令相应的硬指令开发过程 4:可执行程序的调试经汇编,连接生成的可执行程序在操作系统下只要输入文件名就可以运行:
lt301a
操作系统装载该文件进入主存,并开始运行如果出现运行错误,可以从源程序开始排错,也可以利用调试程序帮助发现错误第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2 参数、变量和标号
本节详细讨论汇编语言程序语句的主要部分:
参数 变量名 标号
并引出相关的伪指令和操作符
本节重点掌握:
常数的表达,
变量定义伪指令 DB/DW/DD、
地址操作符和类型操作符第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2.1 数值型参数
在源程序语句格式的 4个组成部分中,
参数是指令的操作对象 ( 学习硬指令时被称为操作数 ),参数之间用逗号分隔
参数根据指令不同可以没有,可以有 1
个,2个或多个
汇编语言程序中,指令参数有数值型,
它的主要形式是常数和数值表达式;
硬指令的操作数有立即数;立即数就要用数值型参数表达第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
1,常数
常数 ( 常量 ) 表示一个固定的数值
它又分成多种形式:
( 1) 十进制常数
( 2) 十六进制常数
( 3) 二进制常数
( 4) 八进制常数
( 5) 字符串常数
( 6) 符号常数第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
2,数值表达式
数值表达式一般是指由运算符连接的各种常数所构成的表达式
汇编程序在汇编过程中计算表达式,最终得到一个数值
程序运行之前,就已经计算出了表达式;所以,程序运行速度没有变慢,但增强程序的可读性
MASM对除伪指令外各种汇编时处理的指令统称为操作符 ( Operator)
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院地址型参数
汇编语言程序中,指令参数还有地址型,
它的主要形式是标号和名字 ( 变量名,段名,过程名等 )
硬指令的操作数有存储单元;存储单元就应该用地址型参数 ( 存储器操作数 ) 表达第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2.2 变量定义伪指令
变量定义 ( Define) 伪指令为变量申请固定长度的存储空间,并可同时将相应的存储单元初始化变量名 伪指令助记符 初值表变量定义伪指令最常使用第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院变量名
变量名为用户自定义标识符,表示初值表首元素的逻辑地址 ;用这个符号表示地址,常称为符号地址
变量名可以没有 。 这种情况,汇编程序将直接为初值表分配空间,无符号地址
设置变量名是为了方便存取它指示的存储单元第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院初值表
初值表是用逗号分隔的参数
主要由数值常数,表达式或?,DUP
组成
? —— 表示初值不确定,即未赋初值;
DUP—— 表示重复初值
DUP的格式为:
重复次数 DUP(重复参数 )
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院变量定义伪指令助记符
变量定义伪指令根据申请的主存空间单位分类
DB—— 定义字节伪指令
DW—— 定义字伪指令
DD—— 定义双字伪指令
DF—— 定义 3字伪指令
DQ—— 定义 4字伪指令
DT—— 定义 10字节伪指令
还有定位伪指令定义字节单元伪指令 DB
DB伪指令用于分配一个或多个字节单元,
并可以将它们初始化为指定值初 值 表 中 每 个 数 据 一 定 是 字 节 量
( Byte),存放一个 8位数据:
可以是 0~255的无符号数或是- 128~+ 127带符号数也可以是字符串常数
data segment ;数据段
X db 'a',-5
db 2 dup(100),?
Y db 'ABC'
data ends
mov al,X;此处 X表示它的第 1个数据,故 AL←'a'
dec X+1;对 X为始的第 2个数据减 1,故成为 -6
mov Y,al;现在 Y这个字符串成为 'aBC'
定义字单元伪指令 DW
DW伪指令用于分配一个或多个字单元,并可以将它们初始化为指定值初 值 表 中 每 个 数 据 一 定 是 字 量
( Word),一个字单元可用于存放任何 16位数据:
一个段地址一个偏移地址两个字符
0~ 65535之间的无符号数
- 32768~+ 32767之间的带符号数
data segment ;数据段
count dw 8000h,?,'AB'
maxintequ 64h
numberdw maxint
array dw maxint dup(0)
data ends
字变量和字常量的定义:
WNUM EQU 5678H ;定义 WNUM为常量
COUNTDW 20H;定义 COUNT变量,假设在数据段的偏移地址为 10H
字变量和字常量的应用:
MOV AX,[BX+SI+WNUM] ; MOV AX,[BX+SI+5678H]
MOV AX,COUNT ; MOV AX,[0010H]
MOV AX,[SI+COUNT] ; MOV AX,COUNT[SI]; MOV AX,[SI+10H]
LEA BX,COUNT ; LEA BX,[0010H]
MOV BX,OFFSET COUNT ; MOV BX,0010H
定义双字单元伪指令 DD
DD伪指令 用于分配一个或多个双字单元,
并可以将它们初始化为指定值初值表中每个数据是一个 32位的双字量
( Double Word),
可以是有符号或无符号的 32位整数也可以用来表达 16位段地址 ( 高位字 ) 和
16位的偏移地址 ( 低位字 ) 的远指针
vardd DD 0,?,12345678h
farpoint DD 00400078h
例 3.2,数据定义综合应用- 1/2
.model small
.stack
.data
bvar DB 16
wvar DW 4*3
dvar DD 4294967295 ;= 232- 1
qvar DQ?
DB 1,2,3,4,5
tvar DT 2345 ;定义了 BCD码 2345H
abc DB 'a','b','c'
msg DB 'Hello',13,10,'$'
bbuf DB 12 DUP('month')
dbuf DD 25 DUP(?)
CALLDOS EQU <int 21h>
例 3.2,数据定义综合应用- 2/2
.code
.startup
mov bl,bvar
mov ax,word ptr dvar[0]
mov dx,word ptr dvar[2] ;取双字到 DX.AX
mov dx,offset msg
mov ah,09h
CALLDOS
.exit 0
end
例 3.3,数据复制和显示- 1/2
.model small
.stack
.data
source db 33h,34h,35h,36h ;定义 4个字符数据
target db 80 dup(?) ;分配数据空间 4× 20=80
.code
.startup
mov ax,ds
mov es,ax ;data也作为附加段
cld
mov si,offset source
mov di,offset target
mov cx,80
例 3.3,数据复制和显示- 2/2
rep movsb ;串传送
mov si,0 ;显示
mov bx,offset target
again,mov dl,[bx+si]
mov ah,2
int 21h
inc si
cmp si,80
jb again
.exit 0
end
定位伪指令定位伪指令控制数据的偏移地址
ORG 参数
ORG伪指令是将当前偏移地址指针指向参数表达的偏移地址:
ORG 100h ;从 100h处安排数据或程序
ORG $+10;使偏移地址加 10,即跳过 10个字节空间
MASM中,符号,$”表示当前偏移地址值第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.2.3 变量和标号的属性
① 地址属性
标号和名字对应存储单元的逻辑地址
逻辑地址包括:段地址和偏移地址
② 类型属性
标号,子程序名的类型可以是 NEAR
( 近 ) 和 FAR( 远 ),分别表示段内或段间
变量名的类型可以是 BYTE( 字节 ),
WORD( 字 ) 和 DWORD( 双字 ) 等地址操作符
取得名字或标号的段地址和偏移地址两个属性
[ ] 将括起的表达式作为存储器地址
$ 当前偏移地址
,采用指定的段地址寄存器
OFFSET 名字 /标号返回名字或标号的偏移地址
SEG 名字 /标号返回名字或标号的段地址
org $+10
array db 45,45h
.code
mov ax,seg array
mov ds,ax
mov bx,offset array;等价于 lea bx,array
mov cl,array+4;等效于 mov cl,array[4]
mov ax,es:[2000h]
加 4个字节单元类型操作符
类型操作符对名字或标号的类型属性进行有关设置类型名 PTR 名字 /标号
THIS 类型名
SHORT 标号
TYPE 名字 /标号
SIZEOF 变量名
LENGTHOF 变量名
PTR操作符类型名 PTR 名字 /标号
PTR操作符使名字或标号具有指定的类型
类型名可以是
BYTE/WORD/DWORD/FWORD/QWORD/TBYTE
或者是 NEAR/FAR,还可以是由 STRUCT,RECORD、
UNION以及 TYPEDEF定义的类型
mov al,byte ptr w_var ;w_var是一个字变量
jmp far ptr n_label ;n_label是一个标号
使用 PTR操作符,可以临时改变名字或标号的类型
THIS操作符
THIS 类型名
利用 THIS说明的操作数具有汇编时的当前逻辑地址,
但具有指定的类型
b_var equ THIS byte;按字节访问变量 b_var,但与 w_var的地址相同
w_var dw 10 dup(0) ;按字访问变量 w_var
f_jump equ THIS far;用 f_jump为段间转移 ( f_jump label far)
n_jump,mov ax,w_var;用 n_jump为段内近转移,但两者指向同一条指令
LABEL伪指令的功能等同于,EQU THIS”
TYPE操作符
TYPE 名字 /标名
返回表明名字或标号类型的一个字量数值
对字节,字和双字变量依次返回 1,2和 4;
对短,近和远转移依次返回 ff01h,ff02h和 ff05h
mov ax,TYPE w_var ;汇编结果为 mov ax,2
mov ax,TYPE n_jump;汇编结果为 mov ax,0ff02h( near标号 )
操作符 SIZEOF返回整个变量占用的字节数
LENGTHOF返回整个变量的数据项数 ( 即元素数 )
SIZEOF = LENGTHOF × TYPE
.model small
.stack
.data
v_byte equ this byte;v_byte是字节类型,与变量 v_word的地址相同
v_word dw 3332h,3735h;v_word是字类型的变量
target dw 5 dup(20h);分配数据空间 2× 5= 10字节
crlf db 0dh,0ah,'$'
flag db 0
n_point dw offset s_label;取得标号 s_label的偏移地址例 3.4:属性及其 应用- 1/5
例 3.4:属性及其 应用- 2/5
.code
.startup
mov al,byte ptr v_word;用 PTR改变 v_word的类型,否则类型不匹配
dec al
mov v_byte,al;对 v_word的头一个字节操作,原为 32H,现为 31H
n_label,cmp flag,1
jz s_label ;flag单元为 1转移
inc flag
jmp n_label ;进行短转移例 3.4:属性及其 应用- 3/5
s_label,cmp flag,2
jz next ;flag单元为 2转移
inc flag
jmp n_point;段内的存储器间接寻址,转移到 s_label标号处
next,mov ax,type v_word;汇编结果为 mov ax,2
mov cx,lengthof target;汇编结果为 mov cx,5
例 3.4:属性及其 应用- 4/5
mov si,offset target
w_again,mov [si],ax ;对字单元操作
inc si ;SI指针加 2
inc si
loop w_again ;循环
mov cx,sizeof target;汇编结果为 mov cx,0ah
mov al,'?'
mov di,offset target
b_again,mov [di],al ;对字节单元操作
inc di ;DI指针加 1
loop b_again ;循环例 3.4:属性及其 应用- 5/5
mov dx,offset v_word;显示结果,1357
mov ah,9
int 21h
.exit 0
end
第 3 章
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院
3.3 程序段的定义和属性
详述汇编语言程序格式的组成部分首先,简单了解 DOS支持的 exe程序和
com程序其次,重点掌握简化段定义格式的各条伪指令最后,理解完整段定义格式所包含的各种段属性
exe程序
利用程序开发工具,通常将生成 EXE结构的可执行程序 ( 扩展名为,EXE的文件 )
它可以有独立的代码,数据和堆栈段,还可以有多个代码段或多个数据段,程序长度可以超过
64KB,执行起始处可以任意指定
当 DOS装入或执行一个程序时,DOS确定当时主存最低的可用地址作为该程序的装入起始点 。 此点以下的区域称为程序段 。 在程序段内偏移 0处,
DOS为该程序建立一个程序段前缀控制块 PSP
( Program Segment Prefix),它占 256( =100h)
个字节;而在偏移 100h处才装入程序本身
com程序
COM程序是一种将代码,数据和堆栈段合一的结构紧凑的程序,所有代码,数据都在一个逻辑段内,不超过 64KB
在程序开发时,需要满足一定要求并采用相应参数才能正确生成 COM结构的程序
COM文件存储在磁盘上是主存的完全影象,不包含重新定位的加载信息,与 EXE文件相比其加载速度更快,占用的磁盘空间也少
尽管 DOS也为 COM程序建立程序段前缀 PSP,但由于两种文件结构不同,所以加载到主存后各段设置并不完全一样;SampleA.ASM
.model small
.stack
.data
..,;在数据段定义数据
.code
.startup
..,;在代码段填入指令序列
.exit 0
..,;子程序代码
end
简化段定义格式
MASM 6.x支持存储模式伪指令
.MODEL 存储模式
使用简化段定义,必须有存储模式伪指令
,model语句必须位于所有段定义语句之前
存储模式决定一个程序的规模,确定进行子程序调用,指令转移和数据访问的缺省属性
MASM有 7种不同的存储模式:
① TINY ② SMALL
③ COMPACT ④ MEDIUM
⑤ LARGE ⑥ HUGE
⑦ FLAT
简化段定义伪指令
.STACK [大小 ] ;堆栈段开始
.DATA ;数据段开始
.CODE [段名 ] ;代码段开始
简化段定义伪指令指明一个逻辑段的开始,同时自动结束前面的一个段采用简化段定义伪指令前,需有,model语句
使用简化段定义,各段名称和其他用户所需的信息可以使用 MASM预定义符号,例如:
@data表示由,data等定义的数据段的段名程序开始伪指令.STARTUP
按照 CPU类型,存储模式,操作系统和堆栈类型,产生程序开始执行的代码;同时还指定程序开始执行的起始点
在 DOS下,还将设置
DS值,调整 SS和 SP值
mov dx,dgroup
mov ds,dx ;设置 DS
mov bx,ss
sub bx,dx
shl bx,1
shl bx,1
shl bx,1
shl bx,1
cli ;关中断
mov ss,dx ;调整 SS和 SP
add sp,bx
sti ;开中断
mov dx,@data
mov ds,dx
程序终止伪指令
.EXIT [返回参数 ]
产生终止程序执行返回操作系统的指令代码
它的可选参数是一个返回的数码,通常用 0
表示没有错误 。 例如,exit 0对应的代码是:
mov ax,4c00h
int 21h
DOS功能调用的 4ch子功能 ( 返回 DOS),
入口参数,AH= 4ch,AL=返回数码汇编结束伪指令
END [标号 ]
指示汇编程序 MASM到此结束汇编过程
源程序的最后必须有一条 END语句
可选的标号用于指定程序开始执行点,连接程序将据此设置 CS,IP值
采用了,startup伪指令就不需要再用,end
标号,指明开始执行点,但还要有 end伪指令
———— 不要糊涂 ————
程序终止和汇编结束是两码事
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院第 3章 教学要求 ( 1)
1,掌握汇编语言语句格式
2,掌握简化段定义源程序格式
3,掌握常量表达,变量定义及应用,变量,标号和逻辑段的属性
4,了解数值表达式和 DOS的程序结构
5,掌握汇编语言源程序的编辑,汇编,连接和调试的开发方法
HTTP://DLS.ZZU.EDU.CN 郑州大学远程教育学院第 3章 教学要求 ( 2)
6,掌握基本伪指令和操作符:
EQU/=,+- */,DB/ DW/ DD,? / DUP
ORG/ $,OFFSET/ SEG/ PTR
.MODEL/,STACK/,DATA/,CODE/ END