收藏 分享(赏)

8086伪指令(汇编语言程序格式).doc

上传人:精品资料 文档编号:10333180 上传时间:2019-10-31 格式:DOC 页数:28 大小:204.22KB
下载 相关 举报
8086伪指令(汇编语言程序格式).doc_第1页
第1页 / 共28页
8086伪指令(汇编语言程序格式).doc_第2页
第2页 / 共28页
8086伪指令(汇编语言程序格式).doc_第3页
第3页 / 共28页
8086伪指令(汇编语言程序格式).doc_第4页
第4页 / 共28页
8086伪指令(汇编语言程序格式).doc_第5页
第5页 / 共28页
点击查看更多>>
资源描述

1、8086 伪指令(汇编语言程序格式)汇编语言程序中的语句可以由指令、伪指令和宏指令组成。上一章我们介绍了 8086 指令系统中的 6类指令,每一条指令都对应一种 CPU 操作。伪指令又称为伪操作,它是在对源程序汇编期间由汇编程序处理的操作,它们可以完成如处理器选择、定义程序模式、定义数据、分配存储区、指示程序结束等功能。宏指令是由用户按照宏定义格式编写的一段程序,其中语句可以是指令、伪指令,甚至是已定义的宏指令。宏指令将在第七章中介绍。伪指令和指令的区别在于,每一条指令必须生成机器代码,然后在程序运行期间由 CPU 来执行其操作;而伪指令是在汇编期间由汇编程序执行的操作命令,除了数据定义及存储

2、器分配伪指令分配存储器空间外,其它伪指令不生成目标码。和各种指令一样,伪指令也是程序设计不可缺少的工具。下面介绍一些常用的伪指令。 4.2.1 段定义伪指令段定义伪指令是表示一个段开始和结束的命令,80x86 有两种段定义的方式:完整段定义和简化段定义,分别使用不同的段定义伪指令来表示各种段。4.2.1.1 完整的段定义伪指令完整段定义伪指令的格式如下:段名 SEGMENT段名 ENDS 段名由用户命名。对于数据段、附加段和堆栈段来说,段内一般是存储单元的定义、分配等伪指令语句;对于代码段中则主要是指令及伪指令语句。定义了段还必须说明哪个段是代码段,哪个段是数据段。ASSUME 伪指令就是建立

3、段和段寄存器关系的伪指令,其格式为:ASSUME 段寄存器名: 段名,段寄存器名必须是 CS、DS、ES 和 SS 中的一个,而段名必须是由 SEGMENT 定义的段名。定位类型:说明段的起始边界值(物理地址)。组合类型:说明程序连接时的段组合方法。类别:在单引号中给出连接时组成段组的类型名。连接程序可把相同类别的段的位置靠在一起。例 4.1; * * * * * * * * * * * * * * * * * * * * * * *data_seg1 segment ; 定义数据段.data_seg1 ends; * * * * * * * * * * * * * * * * * * * *

4、 * * * data_seg2 segment ; 定义附加段.data_seg2 ends; * * * * * * * * * * * * * * * * * * * * * * *code_seg segment ; 定义代码段assume cs:code_seg, ds:data_seg1, es:data_seg2start: ; 程序执行的起始地址; set DS register to current data segmentmov ax, data_seg1 ; 数据段地址 mov ds, ax ; 存入 DS 寄存器; set ES register to current

5、extra segmentmov 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 ; 存入

6、 ES 寄存器如果程序中还定义了堆栈段 STACK_SEG,也需要把段地址装入 SS 中:MOV AX,STACK_SEG ; 堆栈段地址MOV SS,AX ; 存入 ES 寄存器注意,在程序中不需要用指令装入代码段的段地址,因为在程序初始化时,装入程序已将代码段的段地址装入 CS 寄存器了。为了对段定义作进一步地控制,SEGMENT 伪指令还可以增加类型及属性的说明,其格式如下:段名 SEGMENT 定位类型组合类型类别.段名 ENDS 中的内容是可选的,一般情况下,这些说明可以不用。但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要提供类型和属性的说明。表 4.2.1 定位类型

7、:说明段的起始边界值(物理地址)。定位类型 说 明 BYTE 段可以从任何地址边界开始 WORD 段从字 边界开始,即段的起始边界值为偶数 DWORD 段从双字的边界开始,即段的起始边界值为 4 的倍数 PARA 段从小段边界开始,即段的起始边界值为 16 (或 10H) 的倍数 PAGE 段从页边界开始,即段的起始边界值为 256 (或 100H) 的倍数 注意:定位类型的缺省项是 PARA,即在未指定定位类型的情况下,则连接程序默认为 PARA。BYTE 和WORD 用于把其它段(通常是数据段)连入一个段时使用;DWORD 一般用于运行在 80386 及后继机型上的程序。表 4.2.2 组

8、合类型:说明程序连接时的段组合方法。组 合 类 型 说 明 PRIVATE 该段为私有段,连接时将不与其它模块中的同名段合并 PUBLIC 该段连接时将与其它同名段连接在一起,连接次序由连接命令指定 COMMON 该段在 连接时与其它同名段有相同的起始地址,所以会产生覆盖 AT 表达式 段地址表达式的 值,其值必为 16 位但 AT 不能用来指定代码段 MEMORY 与 PUBLIC 同义 STACK 将多个同名堆栈段连接在一起, SP 设置在第一个堆栈段的开始 注意:组合类型的缺省项是 PRIVATE。例 4.2 在连接之前已定义两个目标模块如下:模块 1 SSEG SEGMENT PARA

9、 STACKDSEG1 SEGMENT PARA PUBLIC DataDSEG2 SEGMENT PARACSEG SEGMENT PARA Code模块 2 DSEG1 SEGMENT PARA PUBLIC DataDSEG2 SEGMENT PARACSEG SEGMENT PARA Code以上两个模块分别汇编后产生 .OBJ 文件,经连接程序连接后产生的 .EXE 模块如下:模块 1 CSEG SEGMENT PARA Code模块 2 CSEG SEGMENT PARA Code模块 1+2 DSEG1 SEGMENT PARA PUBLIC Data模块 1 DSEG2 SEG

10、MENT PARA模块 2 DSEG2 SEGMENT PARA模块 1 SSEG SEGMENT PARA STACK4.2.1.2 存储模型与简化段定义伪指令较新版本的汇编程序(MASM5.0 与 MASM6.0)除支持完整段定义伪指令外,还提供了一种新的简单易用的存储模型和简化的段定义伪指令。1 存储模型伪指令存储模型的作用是什么呢?存储模型决定一个程序的规模,也确定进行子程序调用、指令转移和数据访问的缺省属性(NEAR 或 FAR)。当使用简化段定义的源程序格式时,在段定义语句之前必须有存储模型 .MODEL 语句,说明在存储器中应如何安放各个段。MODEL 伪指令的常用格式如下:MO

11、DEL 存储模型 2 简化的段伪指令简化的段定义语句书写简短,语句.CODE、.DATA 和.STACK 分别表示代码数据段和堆栈段的开始,一个段的开始自动结束前面一个段。采用简化段指令之前必须有存储模型语句.MODEL。3与简化段定义有关的预定义符号 汇编程序给出了与简化段定义有关的一组预定义符号,它们可在程序中出现,并由汇编程序识别使用。有关的预定义符号如下:(1)code 由.CODE 伪指令定义的段名或段组名。(2)data 由.DATA 伪指令定义的段名,或由 .DATA 、.DATA?、.CONST 和 .STACK 所定义的段组名。(3)stack 堆栈段的段名或段组名。4简化段

12、定义举例1 存储模型伪指令表 4.2.3 MASM 5.0 和 MASM 6.0 支持的存储模型:存储模型 功 能 适应操作系统Tiny (微型) 所有数据和代码都放在一个段内,其访问都为 NEAR 型,整个程序64K,并会产生.COM 文件。 MS-DOSSmall (小型) 所有代码在一个 64KB 的段内,所有数据在另一个 64KB 的段内(包括数据段,堆栈段和附加段)。MS-DOSWindowsMedium (中型) 所有代码64K 时可放在多个代码段中,转移或调用可为FAR 型。所有数据限在一个段内,DS 可保持不变。MS-DOSWindowsCompact(紧凑型) 所有代码限在一

13、个段内,转移或调用可为 NEAR 型。数据64K 时,可放在多个段中。 MS-DOSWindowsLarge (大型) 允许代码段和数据段都可超过 64K,被放置在有多个段内,所以数据和代码都是远访问。MS-DOSWindowsHuge (巨型)单个数据项可以超过 64K,其它同 Large 模型。 MS-DOSWindowsFlat (平展型) 所有代码和数据放置在一个段中,但段地址是 32 位的,所以整个程序可为 4GB。MASM 6.0 支持该模型。OS/2WindowsNT注意:Small 模型是一般应用程序最常用的一种模型,因为只有一个代码段和一个数据段,所以数据和代码都是近访问的。

14、这种模型的数据段是指数据段、堆栈段和附加段的总和。在 DOS 下用汇编语言编程时,可根据程序的不同特点选择前 6 种模型,一般可以选用 SMALL 模型。另外,TINY 模型将产生 COM 程序,其他模型产生 EXE 程序。FLAT 模型只能运行在 32 位 x86 CPU 上,DOS 下不允许使用这种模型。当与高级语言混合编程时,两者的存储模型应当一致。2 简化的段伪指令表 4.2.4 简化段伪指令的格式如下表:简化段伪指令 功 能 注 释.CODE 段名创建一个代码段段名为可选项,如不给出段名,则采用默认段名。对于多个代码段的模型,则应为每个代码段指定段名。.DATA 创建一个数据段 段名

15、是:_DATA.DATA? 创建无初值变量的数据段 段名是:_BSS.FARDATA 段名建立有初值的远调用数据段可指定段名,如不指定,则将以FAR_DATA 命名。.FARDATA? 段名 建立无初值的远调用数据段可指定段名,如不指定,则将以 FAR_BSS命名。.CONST 建立只读的常量数据段 段名是:CONST.STACK 大小创建一个堆栈段并指定堆栈段大小段名是:stack 。如不指定堆栈段大小,则缺省值为 1KB3与简化段定义有关的预定义符号下面的举例说明预定义符号的使用方法。在完整的段定义情况下,在程序的一开始,需要用段名装入数据段寄存器,如例 4.1 中的mov ax,data

16、_seg1mov ds,ax若用简化段定义,则数据段只用.data 来定义,而并未给出段名,此时可用mov ax,data mov ds,ax这里预定义符号data 就给出了数据段的段名。4简化段定义举例例 4.3.MODEL SMALL.STACK 100H ; 定义堆栈段及其大小.DATA ; 定义数据段.CODE ; 定义代码段START: ; 起始执行地址标号MOV AX, DATA ; 数据段地址MOV DS, AX ; 存入数据段寄存器.MOV AX, 4C00HINT 21HEND START ; 程序结束从例 4.3 可以看出,简化段定义比完整的段定义简单得多。但由于完整的段定

17、义可以全面地说明段的各种类型与属性,因此在很多情况下仍需使用它。4.2.2 段组定义伪指令段组定义伪指令能把多个同类段合并为一个 64KB 的物理段,并用一个段组名统一存取它。段组定义伪指令 GROUP 的格式如下:段组名 GROUP 段名 , 段名 我们已经知道在各种存储模型中,汇编程序自动地把各数据段组成一个段组 DGROUP,以便程序在访问各数据段时使用一个数据段寄存器 DS,而 GROUP 伪指令允许用户自行指定段组。例 4.4 将两个数据段 DSEG1 和 DSEG2 合并在一个段组 DATAGROUP 中。;-DSEG1 SEGMENT WORD PUBLIC DATA.DSEG1

18、 ENDS;-DSEG2 SEGMENT WORD PUBLIC DATA.DSEG2 ENDSMOV AX, DATA ; 数据段地址MOV DS, AX ; 存入数据段寄存器.;-DATAGROUP GROUP DSEG1, DSEG2 ;组合成段组CSEG SEGMENT PARA PUBLIC CODEASSUME CS : CSEG, DS : DATAGROUPSTART: MOV AX, DATAGROUPMOV DS, AX ;DS 赋值为段组地址.MOV AX, 4C00HINT 21HCSEG ENDS;-END START利用 GROUP 伪指令定义段组后,段组内统一为一

19、个段地址,各段定义的变量和标号都可以用同一个段寄存器进行访问。4.2.3 程序开始和结束伪指令在程序的开始可以用 NAME 或 TITLE 作为模块的名字,其格式为:NAME 模块名TITLE 文件名表示源程序结束的伪指令的格式为:END 标号注意:NAME 及 TITLE 伪指令并不是必需的,如果程序中既无 NAME 又无 TITLE 伪指令,则将用源文件名作为模块名。程序中经常使用 TITLE,这样可以在列表文件中打印出标题来。END 伪指令中的“标号“指示程序开始执行的起始地址。如果多个程序模块相连接,则只有主程序的 END 要加上标号,其他子程序模块则只用 END 而不必指定标号。例

20、4.14.3 的最后使用了 END START 伪指令。汇编程序将在遇 END 时结束汇编,并且程序在运行时从 START 开始执行。4.2.4 数据定义及存储器分配伪指令80x86 提供了各种数据及存储器分配伪指令,这些伪指令在汇编程序对源程序进行汇编期间,由汇编程序完成数据类型定义及存 储器分配等功能。数据定义及存储器分配伪指令的格式是:变量 助记符 操作数, ,操作数 ;注释下面介绍 ORG 伪指令以及常用的数据定义伪指令。ORG(origin)ORG 伪指令用来表示起始的偏移地址,紧接着 ORG 的数值就是偏移地址的起始值。ORG 伪操作常用在数据段指定数据的存储地址,有时也用来指定代

21、码段的起始地址。DB(define byte)DB 伪指令用来定义字节,对其后的每个数据都存储在一个字节中。DB 能定义十进制数、二进制数、十六进制数和 ASCII 字符,二进制数和十六进制数要分别用“B“和“H“表示,ASCII 字符用单引号( )括起来。DB 还是唯一能定义字符串的伪操作,串中的每个字符占用一个字节。DW(define word)DW 伪指令用来定义字,对其后的每个数据分配 2 个字节(1 个字),数据的低 8 位存储在低字节地址中,高 8 位存储在高字节地址中,如下例中的变量 DATA8 的数据存储在 0070 字地址中,其中 0070字节存储 0BAH,0071 字节存

22、储 03H。DW 还可存储变量或标号的偏移地址。见左面 DW 伪指令的例子。DD(define doubleword)DD 伪指令用来定义双字,对其后的每个数据分配 4 个字节(2 个字)。该伪指令同样将数据转换为十六进制,并根据低地址存储低字节,高地址存储高字节的规则来存放数据。如下例 DATA15 的存储情况是:00A8:0F2H,00A9H:57H,00AAH:2AH,00ABH:5CH。用 DD 存入地址时,第一个字为偏移地址,第二个字为段地址。DQ(define quadword)DQ 伪指令用来定义 4 字,即 64 位字长的数据,DQ 之后的每个数据占用 8 个字节(4 个字)。

23、DT(define ten bytes)DT 伪指令用来为压缩的 BCD 数据分配存储单元,它虽然可以分配 10 个字节(5 个字),但最多只能输入 18 个数字,要注意的是,数据后面不需要加“H“。左面是 DQ 和 DT 的例子。DUP(duplicate)DUP 伪指令可以按照给定的次数来复制某个(某些)操作数,它可以避免多次键入同样一个数据。例如,把 6 个 FFH 存入相继字节中,可以用下面两种方法,显然用 DUP 的方法更简便些。存入 6 字节的 FFHDATA20 DB 0FFH 0FFH 0FFH 0FFH 0FFH 0FFH;DATA21 DB 6 DUP(0FFH) DUP

24、操作一般用来保留数据区,如用数据定义伪指令“DB 64 DUP(?)“可为堆栈段保留 64 个字节单元。DUP 还可以嵌套,其用法见左例。PTR 属性操作符PTR 指定操作数的类型属性,它优先于隐含的类型属性。其格式为:类型 PTR 变量 常数表达式其中类型可以是 BYTE、WORD、DWORD、FWORD、QWORD 或 TBYTE,这样变量的类型就可以指定了。LABEL 伪指令LABEL 可以使同一个变量具有不同的类型属性。其格式为:变量名 LABEL 类型或 标号 LABEL 类型其中变量的数据类型可以是 BYTE,WORD,DWORD,标号的代码类型可以是 NEAR 或 FAR。数据定

25、义及存储器分配伪指令格式中的“变量“是操作数的符号地址,它是可有可无的,它的作用与指令语句前的标号相同,区别是变量后面不加冒号。如果语句中有变量,那么汇编程序将操作数的第一个字节的偏移地址赋于这个变量。“注释“字段用来说明该伪指令的功能,它也不是必须有的。“助记符“字段说明所用伪指令的助记符。DB(define byte)请看下面数据定义的例子,注意 DB 定义的每个数据的存储情况,左边第一列是汇编程序为数据分配的字节地址,第二列是相应地址中存储的数据或 ASCII 字符(均用十六进制表示)。变量 DATA7 定义了 3 个数据和一个字符串,每个数据或串用“,“分开,它们分别存储在偏移地址 0

26、02E 开始的 6 个字节单元中。表 4.2.5; DB 例子的列表文件0000 19 DATA1 DB 25 ; 十进制数 0001 89 DATA2 DB 10001001B ; 二进制数0002 12 DATA3 DB 12H ; 十六进制数0010 ORG 0010H ; 指定偏移地址为 10h0010 32 35 39 31 DATA4 DB 2591 ; ASCII 码数0018 ORG 0018H ; 指定偏移地址为 18h0018 00 DATA5 DB ? ; 保留一个字节0020 ORG 0020H ; 指定偏移地址为 20h0020 4D 79 20 6E 61 6D D

27、ATA6 DB My name is Joe ; ASCII 码字符65 20 69 73 20 4A6F 65002E 0A 10 02 31 30 42 DATA7 DB 10,10H,10B,10B ; 不同的数据类型 DW(define word)表 4.2.6 ; DW 伪指令例子的列表文件0070 0RG 70H ;指定起始地址0070 03BA DATA8 DW 954 ; 十进制数0072 0954 DATA9 DW 100101010100B ; binary0074 253F DATA10 DW 253FH ; 十六进制数0076 FFFB DATA11 DW -5 ; 负

28、数0080 ORG 80H0080 0009 FFFF 0007 000C DATA12 DW 9,-1,7,0CH,00100000B,100,HI0020 0064 4849 ; 各种类型数DD(define doubleword)表 4.2.7 ; DD 例子的列表文件00A0 ORG 00A0H ; 指定起始地址00A0 FF030000 DATA13 DD 1023 ; 十进制数00A4 5C960800 DATA14 DD 10001001011001011100B ; 二进制数00A8 F2572A5C DATA15 DD 5C2A57F2H ; 十六进制数00AC 230000

29、00 89470300 DATA16 DD 23H,34789H,65533 ; 各种数据FDFF0000DT(define ten bytes)表 4.2.8; DQ、DT 例子的列表文件00C0 ORG 00C0H00C0 C223450000000000 DATA17 DQ 4523C2H ; 十六进制数00C8 4948000000000000 DATA18 DQ HI ; ASCII 字符00D0 0000000000000000 DATA19 DQ ? ; 分配 8 个字节单元00E0 ORG 00E0H00E0 2998564379860000 DATA20 DT 8679435

30、69829 ; 压缩的 BCD 数000000EA 0000000000000000 DATA21 DT ? ; 分配 10 个字节单元0000对数据定义伪指令前面的变量还要注意它的类型属性问题。变量表示该伪指令中的第一个数据项的偏移地址,此外,它还具有一个类型属性,用来表示该语句中的每一个数据项的长度(以字节为单位表示),因此 DB 伪指令的类型属性为 1,DW 为 2,DD 为 4,DQ 为 8,DT 为 10。变量表达式的属性和变量是相同的。汇编程序可以用这种隐含的类型属性来确定某些指令是字指令还是字节指令。下例中变量 OPER1 为字节类型属性,OPER2 为字类型属性,所以第一条 M

31、OV 指令应为字节指令,第二条 MOV 指令应为字指令。而第三条指令的变量表达式 OPER1+1 为字节类型属性,AX 却为字寄存器,第四条指令的 OPER2 为字类型属性,AL 为字节寄存器,因此,汇编程序将指示这两条 MOV 指令出错:“类型不匹配“。OPER1 DB ?, ?OPER2 DW ?, ?. MOV OPER1, 0 ;字节指令MOV OPER2, 0 ;字指令MOV AX, OPER1+1 ;错误指令:类型不匹配MOV AL, OPER2 ;错误指令:类型不匹配PTR 属性操作符下例中的两条 MOV 指令把 OPER1+1 的类型属性指定为字,把 OPER2 的类型属性指定

32、为字节,这样指令中两个操作数的属性就一致了,汇编时就不会出错了。OPER1 DB ?, ?OPER2 DW ?, ?.MOV AX, WORD PTR OPER1+1MOV AL, BYTE PTR OPER2LABEL 伪指令例如:BYTE_ARRAY LABEL BYTEWORD_ARRAY DW 50 DUP (?)在 50 个字数组中的第一个字节的地址赋予两个不同类型的变量名:字节类型的变量 BYTE_ARRAY和字类型变量 WORD_ARRAY。在程序中访问数组单元时,要按指令类型来选择变量,如下面两条指令:MOV WORD_ARRAY + 2,0 ; 字指令,; 把该数组的第 3

33、个和第 4 个字节置 0MOV BYTE_ARRAY + 2,0 ; 字节指令, ; 把该数组的第 3 个字节置 04.2.5 表达式赋值伪操作 EQUEQU 是一个赋值伪操作(伪指令),它给一个数据标号赋于一个常数值,但这个常数不占用存储单元。当这个数据标号出现在程序中时,汇编程序即用它的常数值代替数据标号。EQU 可以在数据段之外使用,甚至可用在代码段中间。= 伪操作赋值伪操作“=“的作用与 EQU 类似。它们之间的区别是,EQU 伪操作中的标号名是不允许重复定义的,而=伪操作是允许重复定义的。使用 EQU 操作的优点可从下面的例子中看出:COUNT EQU 25COUNTER DB CO

34、UNTMOV AL, COUNT假定在数据段和代码段中要多次使用一个数据(如 25),那么在编程时凡是用到 25 的地方都可用数据标号 COUNT 来表示。如果程序想修改这个数据,那么只需修改 EQU 的赋值,而无须修改程序中其它部分,如 COUNTER 和 MOV 语句就不必修改。EQU 还可给表达式赋予一个名字,EQU 的用法举例如下:DATA EQU HEIGHT + 12 ; 地址表达式赋以符号名ALPHA EQU 7 ; 常数赋以符号名BETA EQU ALPHA-2 ; 把 7-2=5 赋以符号名 BETAADDR EQU VAR + BETA ; VAR+5 赋以符号名 ADDR

35、。B EQU BP + 8 ; 变址引用赋以符号名 BP8 EQU DS:BP + 8 ; 加段前缀的变址引用赋以符号名 P8注意:在 EQU 语句的表达式中,如果有变量或标号的表达式,则在该语句前应该先给出它们的定义。如上例,ALPHA 必须在 BETA 之前定义,否则汇编程序将指示出错。例如, TMP EQU 5TMP EQU TMP+1 则是错误语句,因为 TMP 已赋值为 5,就不能再把它定义为其它数值。而 TMP = 5TMP = TMP+1 则是允许使用的,因为=伪操作允许重复定义。第一个语句 TMP 的值为5,第二个语句 TMP 的值就为 6 了。4.2.6 地址计数器与对准伪指

36、令1地址计数器在汇编程序对源程序汇编的过程中,使用地址计数器来保存当前正在汇编的指令的地址。地址计数器的值在汇编语言中可用来表示。当用在伪指令的参数字段时,它所表示的是地址计数器的当前值2EVEN 伪指令EVEN 伪指令使下一个变量或指令开始于偶数字节地址。3 ALIGN 伪指令ALIGN 伪指令使它后面的数据或指令从 2 的整数倍地址开始。其格式为:ALIGN 2n (n 为任意整数)1地址计数器 汇编语言允许用户直接用来引用地址计数器的值,例如指令:JMP + 6它的转向地址是 JMP 指令的首地址加上 6。当用在指令中时,它表示本条指令的第一个字节的地址。在这里,+ 6 必须是另一条指令

37、的首地址。否则,汇编程序将指示出错信息。当用在伪指令的参数字段时,则和它用在指令中的情况不同,它所表示的是地址计数器的当前值。例如指令:ARRAY DW 1, 2, + 4, 3, 4, + 4假设汇编时 ARRAY 分配的偏移地址为 0074H,则汇编后,+ 4 所在的两个字单元: (ARRAY+4)=0078+4=007CH(ARRAY+0A)=007E+4=0082H应当注意,ARRAY 数组中的两个+ 4 得到的结果是不同的,这是由于的值是在不断变化的缘故。当在指令中用到时,它只代表该指令的首地址,而与本身所在的字节无关。2EVEN 伪指令例如:DATA_SEG SEGMENTBYTE

38、_DAT DB ?EVENWORD_DAT DW 100 DUP (?)DATA_SEG ENDS一个字的地址最好从偶地址开始,所以对于字数组为了保证它从偶地址开始,可以在 DW 定义之前用 EVEN 伪指令来达到这一目的。3 ALIGN 伪指令例如:. ALIGN 4ARRAY DD 100 DUP (?)ALIGN 伪指令保证了双字数组 ARRAY 地址边界从 4 的倍数开始。ALIGN 伪指令是将当前偏移地址指针指向 2 的乘方的整数倍的地址,如果源地址指针以指向 2 的乘方的整数倍的地址,则不作调整;否则将指针加以一个数,使地址指针指向下一个 2 的乘方的整数倍的地址。当然,ALIGN

39、 2 和 EVEN 是等价的。4.2.7 基数控制伪指令.RADIX 伪指令.RADIX 可以把默认的基数改变为 216 范围内的任何基数。其格式如下:.RADIX 基数值其中基数值用十进制数来表示。例如:MOV BX, 0FFH ;16 进制数标记为 HMOV BL, 10000101B ;二进制数标记为 BMOV BX, 178 ;10 进制为默认的基数,可无标记.RADIX 16 ;以下程序默认 16 进制数MOV BX, 0FF ;16 进制为默认的基数,可无标记MOV BX, 178D ;10 进制数应加标记 D应当注意,在用 .RADIX 16 把基数定为十六进制后,十进制数后面都

40、应跟字母 D。在这种情况下,如果某个十六进制数的末字符为 D,则应在其后跟字母 H,以免与十进制数发生混淆。4.3.1汇编语言源程序语句的格式汇编语言源程序中的每个语句可以由四项组成,格式如下:名字 操作 操作数 ;注释其中:名字项是指一个标号或变量。操作项是一个操作码的助记符,它可以是指令、伪指令或宏指令名。操作数项由一个或多个表达式组成,它提供为执行所要求的操作而需要的信息。操作数项可以是常数、寄存器、标号、变量或由表达式组成。注释项用来说明程序或语句的功能。“;“为识别注释项的开始。“;“也可以从一行的第一个字符开始,此时整行都是注释,常用来说明下面一段程序的功能。上面四项中带方括号的两

41、项是可选项。各项之间必须用“空格“(space)或“水平制表“(Tab)符隔开。(1) 名字项(2) 操作项(3) 操作数项(4) 注释项(1) 名字项源程序中用下列字符来表示名字:字母 AZ数字 09专用字符 ?、 、-、除数字外,所有字符都可以放在源语句的第一个位置。名字中如果用到则必须是第一个字符。可以用很多字符来说明名字,但只有前面的 31 个字符能被汇编程序所识别。一般说来,名字项可以是标号或变量。它们都用来表示本语句的符号地址,都是可有可无的,只有当需要用符号地址来访问该语句时它才需要出现。 标号:标号在代码段中定义,后面跟着冒号:,它也可以用 LABEL 或 EQU 伪操作来定义

42、。此外,它还可以作为过程名定义,这将在以后的章节中加以说明。 变量:变量在数据段或附加数据段中定义,后面不跟冒号。它也可以用 LABEL 或 EQU 伪操作来定义。变量经常在操作数字段出现。(2)操作项操作项可以是指令、伪指令或宏指令的助记符。对于指令,汇编程序将其翻译为机器语言指令。对于伪指令,汇编程序将根据其所要求的功能进行处理。对于宏指令,则将根据其定义展开。宏指令在第七章中将会专门论述。(3) 操作数项 操作数项由一个或多个表达式组成,多个操作数项之间一般用逗号分开。对于指令,操作数项一般给出操作数地址,它们可能有一个,或二个,或三个,或一个也没有。对于伪操作或宏指令,则给出它们所要求

43、的参数。操作数项可以是常数、寄存器、标号、变量或由表达式组成。(4) 注释项注释项用来说明一段程序、一条或几条指令的功能。对于汇编语言程序来说,注释项的作用是很明显的,它可以使程序容易被读懂,因此汇编语言程序必须写好注释。注释应该写出本条(或本段)指令在程序中的功能和作用,而不应该只写指令的动作。读者在有机会阅读程序例子时,应注意学习注释的写法,在编制程序时,更应学会写好注释。4.3.2 表达式表达式是常数、寄存器、标号、变量与一些操作符相组合的序列,可以有数字表达式和地址表达式两种。在汇编期间,汇编程序按照一定的优先规则对表达式进行计算后可得到一个数值或一个地址。常用的表达式操作符介绍如下:

44、(1) 算术操作符算术操作符有+、-、*、/ 和 MOD。MOD 是指除法运算后得到的余数,如 19/7 的商是 2,而 19 MOD 7 则为 5(余数)。(2) 逻辑操作符 逻辑操作符有:AND(与)、OR(或)、XOR(异或)、NOT(非)。逻辑操作符都是按位操作的,只能用于数字表达式中。逻辑操作符要求汇编程序对其前后两个操作数(或表达式)作指定的逻辑操作。(3) 关系操作符关系操作符有:EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)。关系操作符的两个操作数必须都是数字或是同一段内的两个存储器地址。计算的结果应为逻辑值:结果为真,表示为 0

45、FFFFH;结果为假,则表示为 0。(4) 数值回送操作符 (析值操作符)数值回送操作符有:TYPE、LENGTH、SIZE、OFFSET、SEG 等。数值操作符把一些特征或存储器地址的一部分作为数值回送。 TYPE格式为:TYPE 表达式如果表达式是变量,则汇编程序将回送该变量的以字节数表示的类型:DB 为 1,DW 为 2,DD 为4,DF 为 6,DQ 为 8,DT 为 10。如果表达式是标号,则汇编程序将回送代表该标号类型的数值:NEAR 为 -1,FAR 为 -2。如果表达式为常数,则应回送 0。 LENGTH格式为:LENGTH 变量对于变量中使用 DUP 的情况,汇编程序将回送分

46、配给该变量的单元数,而对于其他情况则送 1。 SIZE格式为:SIZE 变量汇编程序应回送分配给该变量的字节数。但是,此值是 LENGTH 值和 TYPE 值的乘积。 OFFSET格式为:OFFSET 变量或标号汇编程序将回送变量或标号的偏移地址值。 SEG格式为:SEG 变量或标号汇编程序将回送变量或标号的段地址值。(5) 属性操作符属性操作符主要有:PTR、段操作符、SHORT、THIS、HIGH、LOW 等。 PTR格式为:类型 PTR 符号地址PTR 用来给已分配的存储地址(用符号地址表示)赋予另一种属性,使该地址具有另一种类型。类型可有 BYTE、WORD、DWORD、FWORD、Q

47、WORD、TBYTE、NEAR 和 FAR 等几种,所以 PTR 也可以用来建立字、双字、四字或段内及段间的指令单元等。 段操作符段操作符用来表示一个标量、变量或地址表达式的段属性。格式为: 段寄存器地址表达式段名地址表达式组名地址表达式 SHORT用来修饰 JMP 指令中转向地址的属性,指出转向地址是在下一条指令地址的127 个字节范围之内。 THIS格式为: THIS 属性或类型THIS 可以象 PTR 一样建立一个指定类型(BYTE、WORD、DWORD)或指定距离(NEAR 或 FAR)的地址操作数。该操作数的段地址和偏移地址与下一个存储单元地址相同。 HIGH 和 LOW称为字节分离操作符,它接收一个数或地址表达式,HIGH 取其高位字节,LOW 取其低位字节。 操作符的优先级我们知道表达式是常数、寄存器、标号、变量和操作符的组合,在计算表达式时,应该首先计算优先级高的操作符,然后从左

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报