定位类型
|
说 明
|
BYTE
|
段可以从任何地址边界开始
|
WORD
|
段从字边界开始,即段的起始边界值为偶数
|
DWORD
|
段从双字的边界开始,即段的起始边界值为4的倍数
|
PARA
|
段从小段边界开始,即段的起始边界值为16 (或10H) 的倍数
|
PAGE
|
段从页边界开始,即段的起始边界值为256 (或100H) 的倍数
|
组合类型
|
说 明
|
PRIVATE
|
该段为私有段,连接时将不与其它模块中的同名段合并
|
PUBLIC
|
该段连接时将与其它同名段连接在一起,连接次序由连接命令指定
|
COMMON
|
该段在连接时与其它同名段有相同的起始地址,所以会产生覆盖
|
AT 表达式
|
段地址=表达式的值,其值必为16位但AT不能用来指定代码段
|
MEMORY
|
与PUBLIC同义
|
STACK
|
将多个同名堆栈段连接在一起,SP设置在第一个堆栈段的开始
|
存储模型
|
功 能
|
适用操作系统
|
Tiny (微型) | 所有数据和代码都放在一个段内,其访问都为NEAR型,整个程序≤64K,并会产生.COM文件。 | MS-DOS |
Small (小型) | 所有代码在一个64KB的段内,所有数据在另一个64KB的段内(包括数据段,堆栈段和附加段)。 | MS-DOS Windows |
Medium (中型) | 所有代码>64K时可放在多个代码段中,转移或调用可为FAR型。所有数据限在一个段内,DS可保持不变。 | MS-DOS Windows |
Compact(紧凑型) | 所有代码限在一个段内,转移或调用可为NEAR型。数据>64K时,可放在多个段中。 | MS-DOS Windows |
Large (大型) | 允许代码段和数据段都可超过64K,被放置在有多个段内,所以数据和代码都是远访问。 | MS-DOS Windows |
Huge (巨型) | 单个数据项可以超过64K,其它同Large模型 | MS-DOS Windows |
Flat (平展型) | 所有代码和数据放置在一个段中,但段地址是32位的,所以整个程序可为4GB。MASM 6.0支持该模型。 | OS/2 WindowsNT |
简化段伪指令
|
功 能
|
注释
|
.CODE [段名] | 创建一个代码段 | 段名为可选项,如不给出段名,则采用默认段名。对于多个代码段的模型,则应为每个代码段指定段名。 |
.DATA | 创建一个数据段 | 段名是:_DATA |
.DATA? | 创建无初值变量的数据段 | 段名是:_BSS |
.FARDATA [段名] | 建立有初值的远调用数据段 | 可指定段名,如不指定,则将以FAR_DATA命名。 |
.FARDATA? [段名] | 建立无初值的远调用数据段 | 可指定段名,如不指定,则将以FAR_BSS命名。 |
.CONST | 建立只读的常量数据段 | 段名是:CONST |
.STACK [大小] | 创建一个堆栈段并指定堆栈段大小 | 段名是:stack。如不指定堆栈段大小,则缺省值为1KB |
; DB 例子的列表文件 0000 19 DATA1 DB 25 ; 十进制数 0001 89 DATA2 DB 10001001B ; 二进制数 0002 12 DATA3 DB 12H ; 十六进制数 0010 ORG 0010H ; 指定偏移地址为10h 0010 32 35 39 31 DATA4 DB '2591' ; ASCII码数 0018 ORG 0018H ; 指定偏移地址为18h 0018 00 DATA5 DB ? ; 保留一个字节 0020 ORG 0020H ; 指定偏移地址为20h 0020 4D 79 20 6E 61 6D DATA6 DB 'My name is Joe' ; ASCII码字符 65 20 69 73 20 4A 6F 65 002E 0A 10 02 31 30 42 DATA7 DB 10,10H,10B,'10B' ; 不同的数据类型 |
; DW 伪指令例子的列表文件 0070 0RG 70H ;指定起始地址 0070 03BA DATA8 DW 954 ; 十进制数 0072 0954 DATA9 DW 100101010100B ; binary 0074 253F DATA10 DW 253FH ; 十六进制数 0076 FFFB DATA11 DW -5 ; 负数 0080 ORG 80H 0080 0009 FFFF 0007 000C DATA12 DW 9,-1,7,0CH,00100000B,100,'HI' 0020 0064 4849 ; 各种类型数据 |
; DD例子的列表文件 00A0 ORG 00A0H ; 指定起始地址 00A0 FF030000 DATA13 DD 1023 ; 十进制数 00A4 5C960800 DATA14 DD 10001001011001011100B ; 二进制数 00A8 F2572A5C DATA15 DD 5C2A57F2H ; 十六进制数 00AC 23000000 89470300 DATA16 DD 23H,34789H,65533 ; 各种数据 FDFF0000 |
; DQ、DT例子的列表文件 00C0 ORG 00C0H 00C0 C223450000000000 DATA17 DQ 4523C2H ; 十六进制数 00C8 4948000000000000 DATA18 DQ 'HI' ; ASCII字符 00D0 0000000000000000 DATA19 DQ ? ; 分配8个字节单元 00E0 ORG 00E0H 00E0 2998564379860000 DATA20 DT 867943569829 ; 压缩的BCD数 0000 00EA 0000000000000000 DATA21 DT ? ; 分配10个字节单元 0000 |
; DUP例子的列表文件 0100 ORG 0100H ; 数据区的起始地址 0100 0020[ DATA22 DB 32 DUP(?) ; 保留32字节 ?? ] 0120 ORG 0120H 0120 0005[ DATA23 DB 5 DUP(2 DUP(99)); 存入10个字节的99 0002[ 63 ] ] 012A 0008[ ATA24 DW 8 DUP(?) ; 保留8个字节 ???? ] |
4.2.1 处理器选择伪操作
由于80x86的所有处理器都支持8086/8088指令系统,但每一种高档机型又都增加了一些新的指令,因此在编写程序时都要对所用处理器有一个确定的选择。 本组伪操作的就是告诉汇编程序应该选择哪一种指令系统。 本组伪操作,一般放在整个程序的最前面,如不给出处理器选择,则默认为.8086。也可放在程序中,如程序中用了一条80486所增加的指令,则可在该指令的上一行加上.486。 处理器选择伪操作主要有以下几种: .8086 选择8086指令系统 .286 选择80286指令系统 .286 P 选择保护方式下的80286指令系统 .386 选择80386指令系统 .386 P 选择保护方式下的80386指令系统 .486 选择80486指令系统 .486 P 选择保护方式下的80486指令系统 .586 选择Pentium指令系统 .586 P 选择保护方式下的Pentium指令系统
保护方式下的指令系统是指包括特权指令在内的指令系统。
|
返回顶部
|
4.2.2 段定义伪操作 该组伪操作为确定标号和变量(代码段和数据段的符号地址)的偏移地址;把有关信息通过目标模块传送给连接程序,以便连接程序把不同的段和模块连接在一起,形成一个可执行程序。 1.完整的段定义伪操作 段名 segment [定位] [组合] [段字] [ ‘类别’ ] ... ;语句序列 段名 ends 完整段定义由SEGMENT和ENDS这一对伪指令实现,SEGMENT伪指令定义一个逻辑段的开始,ENDS伪指令表示一个段的结束。段定义指 令后的4个关键字用于确定段的各种属性,堆栈段要采用stack组合类型,代码段应具有‘code’类别,其他为可选属性参数。如果不指定,则采用默认参 数;但如果指定,注意要按照上列次序。 语句序列:数据段、附加段、和堆栈段中,一般是存储单元的定义、分配等伪操作;代码段则是指令及伪操作。 (1)定位类型(align_type) 指定逻辑段在主存储器中的边界,可为: PARA 段的起始地址必须从小段边界开始(xxxx 0000b)。这样,偏移地址可以从0开始。 BYTE 该段可以从任何地址开始(xxxx xxxxb),这样起始偏移地址可能不是0。 WORD 该段必须从字的边界开始(xxxx xxx0b),即段起始地址必须为偶数。 DWORD 该段必须从双字的边界开始(xxxxxx00b)。 PAGE 该段必须从页的边界开始(0000 0000b),该地址能被256整除。 默认定位类型: 简化段定义伪指令的代码和数据段默认采用WORD定位,堆栈段默认采用PARA定位。 完整段定义伪指令的默认定位属性是PARA,其低4位已经是0,所以默认情况下数据段的偏移地址从0开始。 (2)组合类型(combine_type) 指定多个逻辑段之间的关系,可为: PRIVATE 该段为私有段,在连接时将不与其他模块中同名分段合并。这是完整段定义伪指令默认的段组合方式。 PUBLIC 该段连接时,可以把不同模块中的同名段相邻地连接在一起,其连接次序由连接命令指定。每一分段都从小段的边界开始,因此个模块的原有段之间可能存在小于16字节的间隙。这是简化段定义伪指令默认的段组合。 MEMORY 与PUBLIC同义。 STACK 把不同模块中的同名段组合而形成一个堆栈段。该段的长度为各原有段的总和,各原有段之间并无PUBLIC所连接段中的间隙,而且栈顶可自动指向连接后形成的大段堆栈段的栈顶。这是堆栈段必须具有的段组合。 COMMON 该段连接时,可以把不同模块中的同名段重叠而形成一个段,由于各同名段有相同的起始地址,所以会产生覆盖。COMMON的连接长度是各分段中的最大长度。重叠部分的内容取决于排列在最后一段的内容。 AT expression 使段地址是表达式所计算出来的16位值。但它不能用来指定代码段。
(3)使用类型(use_type)
为支持32位段而设置的属性,只适用于386及其后继机型。它用来说明使用16位寻址方式还是32位寻址方式。它们可以是: USE16 使用16位寻址方式。 USE32 使用32位寻址方式。 当使用16位寻址方式时,段长<=64KB,地址的形式是16位段地址和16偏移地址;当使用32位寻址方式时,段长可大4GB,地址的形 式是16位段地址和32位偏移地址。编写运行于实模式(8086工作方式)的汇编语言程序,必须采用USE16。使用类型的默认项是USE16。 (4)类别(‘class’) 在引号中给出连接时组成段组的类型名,段组的类型名可以是任意名称。类型说明并不能把相同类别的段合并起来,但在连接程序组织段时,可将所有的同 类别段相邻分配。大多数MASM程序使用 ‘code’、‘data’和‘stack’来分别指名代码段、数据段和堆栈段,以保持所有代码和数据的连续。
指定段寄存器伪指令ASSUME
ASSUME 段寄存器:段名 [,段寄存器名:段名, ...] 通知MASM用指定的段寄存器来寻址对应的逻辑段,即明确段和段寄存器的关系。 ASSUME说明分配情况。汇编程序会根据数据所在的逻辑段,在需要时自动插入段超越前缀。这是ASSUME伪指令的主要功能。其中段寄存器必须 是CS、DS、ES、SS(386及其后继机型还有FS和GS)之一,段名则必须是由SEGMENT定义的段中的段名。 ASSUME伪指令并不为段寄存器设定初值,连接程序LINK将正确设置CS : IP和SS : SP。 由于数据段通常都需要,所以在样板源程序中,首先为DS赋值;如果使用附加段,还要赋值ES。 ASSUME NOTHING则可取消前面由ASSUME所指定的段寄存器。 完整段定义举例说明例4.1。 ASSUME并不能把段地址装入段寄存器中,所以代码段中要有这样的操作。如果有堆栈段,也需把段地址装入SS中。代码段不需要,代码段的这一操作是在程序初始化时完成的。 2. 存储模型与简化段定义伪操作 (1) MODEL伪操作 .MODEL 存储模式 [,模式选项] 使用简化段定义,必须有存储模式伪指令。 .model语句必须位于所有段定义语句之前。用来说明在存储器中是如何安放各个段的。 存储模式决定一个程序的规模,确定进行子程序调用、指令转移和数据访问的缺省属性。 MASM有7种不同的存储模式: ① TINY ② SMALL ③ MEDIUM ④ COMPACT ⑤ LARGE ⑥ HUGE ⑦ FLAT ① Tiny 微型模式是MASM 6.0才引入的,用于创建COM类型程序,COM程序必须从0100H的存储单元开始。这种模型一般用于小程序。用微型模式编写汇编语言程序时,所有的段 地址寄存器都被设置为同一值。这意味着代码段、数据段、堆栈段都在同一个段内,不大于64KB;访问操作数或指令都只需要使用16位偏移地址。
② Small
一般的程序(例如本书的绝大多数程序示例和习题)都可用这种模式。在小型模式下,一个程序至多只能有一个代码段和一个数据段,每段不大于 64KB。这里的数据段是指数据段、堆栈段和附加段的总和,它们共用同一个段基址,总长度不可超过64KB;因此小模式下程序的最大长度为128KB。访 问操作数或指令都只需要使用16位偏移地址;这意味着诸如指令转移、程序调用以及数据访问等都是近属性(NEAR),即小型模式下的调用类型和数据指针缺 省分别为近调用和近指针。 ③ Medium 中型模式是与紧凑模式互补的模式。适合于数据量小但代码量大的程序。中型模式的代码段可以超过64KB,有多个;但数据段只能有一个不大于 64KB的段。这种模式下数据是近访问;但代码则是远访问,即调用类型缺省是远(FAR)调用,因为要利用段地址区别多个代码段。
④ Compact
适合于数据量大但代码量小的程序。紧凑模式下,代码段被限制在一个不大于64KB的段内;而数据段则可以有多个,超过64KB。这种模式下的代码是近访问,即调用类型缺省仍为近调用;而数据则缺省为远(FAR)访问,因为必须用段地址来区别多个数据段。
⑤ Large
较大型程序通常采用的存储模式。大型模式允许的代码段和数据段都有多个,都可以超过64KB;但全部的静态数据(不能改变的数据)仍限制在64K字节内。大型模式下的数据和代码都可以远访问。 ⑥ Huge HUGE(巨型模式)与大型模式基本相同,只是静态数据不再被限制在64K字节之内。
⑦ Flat
平展模式用于创建一个32位的程序,它只能运行在32位x86 CPU上。DOS下不能使用FLAT模式,而编写32位Windows 9.x或Windows-NT的程序时,必须采用FLAT模式。MASM5版本不支持这种模型,当MASM6可以支持。
DOS下编程可选择前六种模式,一般可以选用SMALL模式。TINY模式产生COM程序,其他模式产生EXE程序,FLAT模式只能用于32位程序。
Model options允许用户指定三种选项:
高级语言接口:该汇编程序作为某一高级语言程序的过程而为该高级语言程序调用时,应该用C,BASIC,FORTRAN,PASCAL等来说明。 操作系统:说明程序运行于哪个操作系统之下,可用OS_DOS或OS_OS2来说明,默认项是OS_DOS。 堆栈距离:可用NEARSTACK 或FARSTACK来说明。NEARSTACK是指把堆栈段和数据段组合到一个DGROUP段中,DS和SS均指向DGROUP段;FARSTACK是指堆栈段和数据段并不合并。 当存储模型为TINY、SMALL、MEDIUM和FLAT时,默认项是NEARSTACK;当存储模型为COMPACT、LARGE和HUGE时,默认项是FARSTACK。 例如: . MODEL SMALL , C . MODEL LARGE , PASCAL , OS_DOS , FARSTACK (2)简化的段定义伪操作 汇编程序给出的标准段有下列几种: Code 代码段 Initialized data 初始化数据段 Uninitialized data 未初始化数据段 Far initialized data 远初始化数据段 Far uninitialized data 远未初始化数据段 Constants 常数段 Stack 堆栈段 这种分段方法把数据段分得更细,可便于与高级语言的兼容。在为高级语言编写某一个汇编过程时,可采用这种标准段模式。 若编写一个独立的汇编语言程序,不需要细分。一般采用下述三个标准段即可。 .CODE .DATA .STACK 简化段定义伪指令指明一个逻辑段的开始,同时自动结束前面的一个段。 采用简化段定义伪指令前,需有.model语句。 使用简化段定义,各段名称和其他用户所需的信息可以使用MASM预定义符号,例如:@data表示由.data等定义的数据段的段名。 对于以上标准段,可有以下简化段伪操作: 堆栈段伪指令 .STACK [大小] 堆栈段伪指令.STACK创建一个堆栈段,段名是:stack。 它的参数指定堆栈段所占存储区的字节数,默认是1KB(= 1024 = 400h字节)。 数据段伪指令 .DATA 数据段伪指令.data创建一个数据段,段名是:_DATA。它用于定义具有初值的变量,当然也允许定义无初值的变量。 代码段伪指令 .CODE [段名] 代码段伪指令.code创建一个代码段,它的参数指定该代码段的段名。
(3)与简化段定义有关的预定义符号
汇编程序给出了与简化段定义有关的一组预定义符号,它们可在程序中出现,并由汇编程序识别使用。 如在完整段定义下,在程序一开始,需要用段名装入相应寄存器,如例4.1中的相应语句。 若用简化段定义,则数据段只用.DATA来定义,而并未给出段名,此时可用 mov ax ,@data mov ds , ax 另外,还有一些预定义符号,它们也可与条件汇编伪操作相配合,以帮助用户编写一些较为复杂的代码。这里不作介绍。预定义符号@data给出了段名 (4)用MODEL定义存储模型时的段默认属性 表4.1给出了使用MODEL伪操作时的段默认情况。 模型列给出了可定义的7种模型; 伪操作列给出了对应每一种模型可定义7种段的伪操作;
(5)简化段定义举例 例4.2、例4.3、例4.4 3. 段组定义伪操作 汇编程序自动地把各数据段组成一个64KB段组DGROUP,以便程序在访问各数据段时使用一个数据段寄存器DS。 格式:grpname DGROUP segname[, segname] 其中,grpname为段组名,segname则为段名。 DGROUP伪操作允许用户自行指定段组。 定义段组后,段组内各段就统一为一个段地址,各段定义的变量和标号的偏移地址就相对于段组基地址计算。offset操作符取变量和标号相对于段组 的偏移地址,如果没有段组则取得相对于段的偏移地址。offset后可以跟段组中的某个段名,表示该段最后一个字节后面字节相对于段组的偏移地址。 4. 段顺序伪操作 .SEG ;按照源程序的各段顺序 .DOSSEG ;按照微软使用的标准DOS规定 .ALPHA ;按照段名的字母顺序 段顺序伪指令确定各逻辑段在主存的前后位置。 完整段定义格式中,默认按照源程序各段的书写顺序安排(即.seg)。 采用.model伪指令的简化段定义格式,则是规定的标准DOS程序顺序( 即.dosseg ): |
返回顶部
|
4.2.3 程序开始和结束伪操作 1. 程序开始处的伪操作 在程序的开始处可以用NAME或TITLE作为模块的名字。 格式: NAME module_name 或 TITLE text 汇编程序将以给出的module_name或text中的前六个字符作为模块名。Text最多可有60个字符。 TITLE伪操作可指定列表文件的每一页上打印的标题。 如果程序中既无NAME又无TITLE伪操作,则将用源文件名作为模块名。 NAME或TITLE伪操作并不是必要的,但一般经常使用TITLE,以便在列表文件中打印出标题来。 2. 汇编结束伪操作 表示源程序结束的伪操作。 格式: END [label] 可选的标号label指示程序开始执行的起始地址,连接程序将据此设置CS : IP值。如果多个程序模块相连接,则只有主程序要使用标号,其他子程序模块则只用END而不必指定标号。 指示汇编程序MASM到此结束汇编过程。源程序的最后必须有一条END语句。 例4.1~4.5已使用END START表示程序结束,而程序则从START开始执行。 3. 程序开始伪操作 MASM6.0增加了这个伪操作。 .STARTUP 用来定义程序的初始入口点,并且产生设置DS,SS和SP的代码。如果程序中使用了.STARTUP,则结束程序的END为操作中不必再指定程序的入口点标号。 4. 程序中止伪操作 MASM6.0增加了这个伪操作。 .EXIT [return_value] 用来产生退出程序并返回操作系统的代码。Return_value为返回给操作系统的值,常用0作为返回值。 例如.exit 0对应的代码是: mov ax,4c00h int 21h DOS功能调用的4ch子功能(返回DOS): 入口参数:AH=4ch,AL=返回数码 退出程序与汇编结束是两码事。 |
返回顶部
|
4.2.4 数据定义及存储器分配伪操作 该类伪操作又称变量定义伪指令。 变量定义(Define)伪指令为变量申请固定长度的存储空间,并可同时将相应的存储单元初始化。 变量名 伪指令助记符 初值表 格式: [Variable] Mnemonic Operand , … , Operand [;Commnet]
变量名(variable)为用户自定义标识符,表示初值表首元素的逻辑地址;用这个符号表示地址,常称为符号地址。变量名可以没有。这种情况,汇编程序将直接为初值表分配空间,无符号地址。设置变量名是为了方便存取它指示的存储单元。
初值表是用逗号分隔的参数。主要由数值常数、表达式或?、DUP组成: ?――表示初值不确定,即未赋初值; DUP――表示重复初值。 DUP的格式为: Repeat_count DUP (operand , … , opreand) 其中repeat_count可以是一个表达式,它的值应该是一个正整数,用来指定括号中的操作数的重复次数。 变量定义伪指令助记符(Mnemonic),根据申请的主存空间单位分类,说明所定义的数据类型。 DB――定义字节伪指令 DW――定义字伪指令 DD――定义双字伪指令 DF――定义3字伪指令 DQ――定义4字伪指令 DT――定义10字节伪指令 这些伪操作可以把其后跟着的数据存入指定的存储单元,形成初始化数据;或者只分配存储空间而并不存入确定的数值,形成未初始化数据。 1. 定义字节单元伪指令DB DB伪指令用于分配一个或多个字节单元,并可以将它们初始化为指定值。初值表中每个数据一定是字节量(Byte),存放一个8位数据: 可以是0~255的无符号数 或是-128~+127带符号数 也可以是字符串常数
2. 定义字单元伪指令DW
DW伪指令用于分配一个或多个字单元,并可以将它们初始化为指定值。初值表中每个数据一定是字量(Word),一个字单元可用于存放任何16位数据: 一个段地址 一个偏移地址 两个字符 0~65535之间的无符号数 -32768~+32767之间的带符号数
3. 定义双字单元伪指令DD
DD伪指令用于分配一个或多个双字单元,并可以将它们初始化为指定值。初值表中每个数据是一个32位的双字量(Double Word): 可以是有符号或无符号的32位整数 也可以用来表达16位段地址(高位字)和16位的偏移地址(低位字)的远指针 vardd DD 0,?,12345678h farpoint DD 00400078h
4. 其他数据单元定义伪指令
定义3字伪指令DF――用于为一个或多个6字节变量分配空间及初始化。6字节常用在32位CPU中表示一个48位远指针(16位段选择器:32位偏移地址) 定义4字伪指令DQ――用于为一个或多个8字节变量分配空间及初始化。8字节变量可以表达一个64位整数 定义10字节伪指令DT――用于为一个或多个10字节变量分配空间及初始化。10字节变量可以表达扩展精度浮点数
例4.7 DATA_BYTE DB 10 , 4, 10H DATA_WORD DW 100 , 100H , -5 DATA_DW DD 3*20 , 0FFFDH 汇编程序可以在汇编期间在存储器中存入数据,如图4.2所示。 例4.8 MESSAGE DB ‘HELLO’ DB ‘AB’ DW ‘AB’ 则存储器存储情况如图4.5所示。 例4.9 操作数?可以保留存储空间,但不存入数据。如: ABC DB 0 , ? , ? , ? , 0 DEF DW ? , 52 , ? 经汇编后的存储情况如图4.4所示。 例4.11 DUP操作可以嵌套,例如: ARRAY3 db 100 dup(0 , 2 dup(1 , 2) ,0 , 3) 则汇编后的结果如图4.6所示。 例4.10 ARRAY1 DB 2 DUP(0 , 1 , 2 , ?) ARRAY2 DB 100 DUP(?) 汇编后的存储情况如图4.5所示。 例4.12 PARAMETER_TABLE DW PAR1 DW PAR2 DW PAR3 INTERSEG_DATA DD DATA1 DD DATA2 则汇编程序的存储情况如图4.7所示。 386及其后继机型具有16位段地址及32位偏移地址组成的48位远地址,可用DF伪指令来定义。 例4.13 .386 Dataseg segment para use32 ‘data’ Parse_table db 2048 dup(0) Tblptr df Parse_table Dataseg ends 汇编后的存储情况如图4.8所示。 5. 变量定义伪指令使用说明 操作数中的变量或标号可以是表达式,汇编后,存储器中应该存入表达式的值。 DB、DW、DD、DF、DQ、DT等伪操作在MASM6中可用BYTE、WORD、DWORD、FWORD、QWORD、TBYTE来取代,其含义是等同的。 |
返回顶部
|
4.2.5 表达式赋值伪操作 符号定义伪指令:用于常量定义,利用一个标识符表达的一个数值。 等价EQU伪指令:Expression_name EQU Expression 符号名 EQU 数值表达式 符号名 EQU <字符串> 其中符号名不允许重复定义。 等号=伪指令 符号名 = 数值表达式 符号名允许重复定义。 常数若使用有意义的符号名来表示,可以提高程序的可读性,同时更具有通用性。
例:
CONSTANT EQU 256 ;数赋以符号名 DATA EQU HEIGHT+12 ;地址表达式赋以符号名
ALPHA EQU 7
BETA EQU ALPHA-2 ADDR EQU VAR+BETA B EQU [BETA] ;变址引用赋以符号名B P8 EQU DS:[BP+8] ;加段前缀的变址引用赋以 符号名P8 必须注意:在EQU语句的表达式中,如果有变量或标号的表达式,则在该语句前应该先给出它们的定义。 例如:AB EQU DATA_ONE+2 则必须放在DATA_ONE的定义之后才行,否则汇编程序将出错。 例: ;****************************************** EMP EQU 7 ;EMP的值为7 … EMP EQU EMP+1 ;错误 ;这种情况不允许 ;****************************************** … EMP=7 ;EMP的值为7 … EMP=EMP+1 ;EMP的值为8 ;这种情况是允许的 |
返回顶部
|
4.2.6 地址计数器与对准伪操作 1. 地址计数器$ 地址计数器(location counter)用来保存当前正在汇编的指令的偏移地址。当开始汇编或在每一段开始时,把地址计数器初始化为零。汇编过程中,每处理一条指令,地址计数器 就增加一个值,此值为该指令所需要的字节数。地址计数器的值可用符号“$”表示。汇编语言允许用户直接用$来引用地址计数器的值。
例如:
指令JNS $+6的转向地址为JNS指令的首地址加上6。 当$用在指令中时,它表示本条指令的第一个字节的地址。这里,$+6必须是另一条指令的首地址。否则,汇编程序将指示出错信息。 当$用在伪操作的参数字段时,则表示地址计数器的当前值。 例4.17 ARRAY DW 1 , 2 , $+4 , 3 , 4 , $+4 这里,$表示当前偏移地址。汇编后的存储区如图4.9所示。 2. ORG伪操作 定位伪指令控制数据的偏移地址。 ORG 参数 或 ORG constant expression ORG伪指令是将当前偏移地址指针指向参数表达的偏移地址。 ORG 100h ;从100h处安排数据或程序 ORG $+10 ;使偏移地址加10,即跳过10个字节空间 如常数表达式的值为n,则ORG伪操作可以使下一个字节的地址成为常数表达式的值n 。 常数表达式也可以表示从当前已定义过的符号开始的位移量,或表示从当前地址计数器值$开始的位移量。 3. EVEN伪操作 EVEN ;从偶地址开始 EVEN伪指令使下一个变量或指令开始于偶数字节地址。 EVEN伪操作可以保证字数组从偶数地址开始。 例如:DATA_SEG SEGMENT … EVEN WORD_ARRAY DW 100 DUP(?) … DATA_SEG ENDS 4. ALIGN伪操作 ALIGN n ;从n的整数倍地址开始 ALIGN伪操作是将当前偏移地址指针指向n(n是2的乘方)的整数倍的地址。如果原地址指针已指向n的整数倍地址,则不做调整;否则将指针加以1~n-1中的一个数,使地址指针指向下一个n的整数倍地址。ALIGN 2与EVEN等价。 Data segment data01 db 1,2,3 ;data01的偏移地址为0000h even ;等价于align 2 data02 dw 5 ;data02的偏移地址为0004h align 4 data03 dd 6 ;data03的偏移地址为0008h org $+10h data04 db ‘abc’ ;data04的偏移地址为001ch Data ends |
返回顶部
|
4.2.7 基数控制伪操作 MASM提供基数控制.RADIX伪指令可以改变默认进制,其格式是: .RADIX n 其中,n用来表示基数值(用十进制数表示)。 例如: MOV BX , 0FFH .RADIX 16 与 MOV BX , 178 MOV BX , 0FFH MOV BX , 178D 是等价的。 .RADIX 16把基数定位十六进制后,十进制数后面都应跟字母D。如果某个十六进制数的末字符为D,则应在其后跟字母H,以免与十进制数发生混淆。 |