8086伪指令
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
8086伪指令(汇编语言程序格式)
汇编语言程序中的语句可以由指令、伪指令和宏指令组成。上一章我们介绍了8086指令系统中的6
类指令,每一条指令都对应一种CPU操作。
伪指令又称为伪操作,它是在对源程序汇编期间由汇编程序处理的操作,它们可以完成如处理器选择、定义程序模式、定义数据、分配存储区、指示程序结束等功能。
宏指令是由用户按照宏定义格式编写的一段程序,其中语句可以是指令、伪指令,甚至是已定义的宏指令。宏指令将在第七章中介绍。
伪指令和指令的区别在于,每一条指令必须生成机器代码,然后在程序运行期间由CPU来执行其操作;而伪指令是在汇编期间由汇编程序执行的操作命令,除了数据定义及存储器分配伪指令分配存储器空间外,其它伪指令不生成目标码。和各种指令一样,伪指令也是程序设计不可缺少的工具。下面介绍一些常用的伪指令。
4.2.1 段定义伪指令
段定义伪指令是表示一个段开始和结束的命令,80x86有两种段定义的方式:完整段定义和简化段定义,分别使用不同的段定义伪指令来表示各种段。
4.2.1.1 完整的段定义伪指令
完整段定义伪指令的格式如下:
段名 SEGMENT
.
.
.
段名 ENDS
段名由用户命名。对于数据段、附加段和堆栈段来说,段内一般是存储单元的定义、分配等伪指令语句;对于代码段中则主要是指令及伪指令语句。
定义了段还必须说明哪个段是代码段,哪个段是数据段。ASSUME伪指令就是建立段和段寄存器关系的伪指令,其格式为:
ASSUME 段寄存器名: 段名,…
段寄存器名必须是CS、DS、ES和SS中的一个,而段名必须是由SEGMENT定义的段名。
·定位类型:说明段的起始边界值(物理地址)。
·组合类型:说明程序连接时的段组合方法。
·类别:在单引号中给出连接时组成段组的类型名。连接程序可把相同类别的段的位置靠在一起。
例4.1
; * * * * * * * * * * * * * * * * * * * * * * *
data_seg1 segment ; 定义数据段
.
.
.
data_seg1 ends
; * * * * * * * * * * * * * * * * * * * * * * *
data_seg2 segment ; 定义附加段
.
.
.
data_seg2 ends
; * * * * * * * * * * * * * * * * * * * * * * *
code_seg segment ; 定义代码段
assume cs:code_seg, ds:data_seg1, es:data_seg2
start: ; 程序执行的起始地址
; set DS register to current data segment
mov ax, data_seg1 ; 数据段地址
mov ds, ax ; 存入DS寄存器
; set ES register to current extra segment
mov ax, data_seg2 ; 附加段地址
mov es, ax ; 存入ES寄存器
.
.
.
code_seg ends ; 代码段结束
; * * * * * * * * * * * * * * * * * * * * * * * * * *
end start
由于ASSUME伪指令只是指定某个段分配给哪一个段寄存器,它并不能把段地址装入段寄存器中,所以在代码段中,还必须把段地址装入相应的段寄存器中:
MOV AX,DATA_SEG1 ; 数据段地址
MOV DS,AX ; 存入DS寄存器
MOV AX,DATA_SEG2 ; 附加段地址
MOV ES,AX ; 存入ES寄存器
如果程序中还定义了堆栈段STACK_SEG,也需要把段地址装入SS中:
MOV AX,STACK_SEG ; 堆栈段地址
MOV SS,AX ; 存入ES寄存器
注意,在程序中不需要用指令装入代码段的段地址,因为在程序初始化时,装入程序已将代码段的段地址装入CS寄存器了。
为了对段定义作进一步地控制,SEGMENT伪指令还可以增加类型及属性的说明,其格式如下:
段名SEGMENT [定位类型][组合类型]['类别']
.
.
.
段名ENDS
[ ]中的内容是可选的,一般情况下,这些说明可以不用。但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要提供类型和属性的说明。
表4.2.1 ·定位类型:说明段的起始边界值(物理地址)。
定位类型说明
BYTE 段可以从任何地址边界开始
WORD 段从字边界开始,即段的起始边界值为偶数
DWORD 段从双字的边界开始,即段的起始边界值为4的倍数
PARA 段从小段边界开始,即段的起始边界值为16 (或10H) 的倍数
PAGE 段从页边界开始,即段的起始边界值为256 (或100H) 的倍数
注意:
定位类型的缺省项是PARA,即在未指定定位类型的情况下,则连接程序默认为PARA。BYTE和WORD 用于把其它段(通常是数据段)连入一个段时使用;DWORD一般用于运行在80386及后继机型上的程序。
表4.2.2 ·组合类型:说明程序连接时的段组合方法。
组合类型说明
PRIVATE 该段为私有段,连接时将不与其它模块中的同名段合并
PUBLIC 该段连接时将与其它同名段连接在一起,连接次序由连接命令指定
COMMON 该段在连接时与其它同名段有相同的起始地址,所以会产生覆盖
AT 表达式段地址=表达式的值,其值必为16位但AT不能用来指定代码段
MEMORY 与PUBLIC同义
STACK 将多个同名堆栈段连接在一起,SP设置在第一个堆栈段的开始
注意:组合类型的缺省项是PRIVATE。
例4.2 在连接之前已定义两个目标模块如下:
模块1 SSEG SEGMENT PARA STACK
DSEG1 SEGMENT PARA PUBLIC 'Data'
DSEG2 SEGMENT PARA
CSEG SEGMENT PARA 'Code'
模块2 DSEG1 SEGMENT PARA PUBLIC 'Data'
DSEG2 SEGMENT PARA
CSEG SEGMENT PARA 'Code'
以上两个模块分别汇编后产生 .OBJ 文件,经连接程序连接后产生的 .EXE模块如下:
模块1 CSEG SEGMENT PARA 'Code'
模块2 CSEG SEGMENT PARA 'Code'
模块1+2 DSEG1 SEGMENT PARA PUBLIC 'Data'
模块1 DSEG2 SEGMENT PARA
模块2 DSEG2 SEGMENT PARA
模块1 SSEG SEGMENT PARA STACK
4.2.1.2 存储模型与简化段定义伪指令
较新版本的汇编程序(MASM5.0与MASM6.0)除支持完整段定义伪指令外,还提供了一种新的简单易用的存储模型和简化的段定义伪指令。
1.存储模型伪指令
存储模型的作用是什么呢?存储模型决定一个程序的规模,也确定进行子程序调用、指令转移和数据访问的缺省属性(NEAR或FAR)。当使用简化段定义的源程序格式时,在段定义语句之前必须有存储模型 .MODEL语句,说明在存储器中应如何安放各个段。
MODEL伪指令的常用格式如下: