ASSUME
指定各段与寄存器的关系; 数据段定义
DATAS SEGMENT
TESTDATA DB 1,2,3,4
TESTDATA1 DB 5,6,7,8
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START: ; 程序开始
MOV AX,DATAS ; 装填寄存器
MOV DS,AX
; 程序代码
MOV AH,4CH ; 程序退出
INT 21H
CODES ENDS ; 代码段结束
END START ; 汇编结束,并指定程序执行的起点
表达式可以作为各指令的操作数。其值可以在汇编的时候确定。
标号/变量:存储的是地址,拥有段值、偏移量、类型三种属性
表达式:数字表达式 地址表达式
算术操作符: + 、- 、*、/、mod
逻辑和移位运算符:AND、OR、XOR、NOT、SHL(左移位)、SHR(右移位)
关系运算符:EQ(相等)、NE(不相等)、LT(小于)、LE(小于等于)、GT(大于)、GE(大于等于)
数值回送运算符:
运算符 | 说明 |
---|---|
SEG expression | 分离出其后变量或标号所在段的段地址 |
OFFSET expression | 分离出其后变量或标号所在段的偏移地址 |
TYPE expression | 如果是变量,将返回该变量的类型对应字节数; 如果是标号,则返回代表标号类型的数值(NEAR=-1,FAR=-2)。 |
LENGTH expression | 取出变量所含的数据存储单元个数。 对于DUP 定义的变量,返回重复的次数,否则返回1 |
SIZE expression | 等于 LENGTH 变量 * TYPE 变量 |
示例
DATA SEGMENT
A DB ‘ABCDEF’, 5 DUP( 0 )
B DW 10 DUP(1,2 DUP( 2 ) )
C DB 3,20 DUP(0)
D DB 3 DUP( 5 ), 0,10 DUP( ? )
DATA ENDS
MOV AX,LENGTH A ; AX=1
MOV BX,LENGTH B ; BX=10
MOV CX,LENGTH C ; CX=1
MOV DX,LENGTH D ; DX=3
type PTR expression
用于指定表达式的类型,type 有 byte
, word
等段名:表达式
用于指定一个变量或标号的段地址数据类型 | 大小LENGTH 变量
|
---|---|
BYTE |
1 |
WORD |
2 |
DWORD |
3 |
FWORD |
4 |
QWORD |
8 |
TWORD |
10 |
标号:
,表示一行代码的起始地址数据类型 | 大小LENGTH 变量
|
说明 |
---|---|---|
NEAR PTR |
-1 | 近地址类型 |
FAR PTR |
-2 | 远地址类型 |
伪操作是汇编程序对源程序进行汇编时处理的操作,完成处理器选择、存储模式定义、数据定义、存储器分配、指示程序开始结束等功能。
指令 | 说明 |
---|---|
.8086 | (默认)选择8086指令系统 |
.286 | 选择80286指令系统 |
.286P | 选择保护模式下的80286指令系统 |
.386 | 选择80386指令系统 |
.386P | 选择保护模式下的80386指令系统 |
.486 | 选择80486指令系统 |
.486P | 选择保护模式下的80486指令系统 |
.586 | 选择Pentium指令系统 |
.586P | 选择保护模式下的Pentium指令系统 |
段名 segment 定位 组合 段字 '类别'
... ;语句序列
段名 ends
值 | 说明 |
---|---|
PARA | (默认) 表示本段必须从能被16整除的地址处开始存放,即段起始地址最低四位必须是0 |
WORD | 表示本段要从一个偶数地址处开始存放,即段起始地址的最低一位必须是0 |
BYTE | 表示本段起始地址可以从任一地址处开始存放 |
PAGE | 表示本段要从能被256整除的地址处开始存放,即起始地址的最低八位必须是0 |
值 | 说明 | 注意 |
---|---|---|
PRIVATE | (默认) 本段与其他段没有逻辑关系,不与其他段合并,每段都有自己的段地址 | |
PUBLIC | 连接程序把本段与所有同名同类型的其他段相邻地连接在一起,然后为所有这些段指定一个共同的段地址,也就是合成一个物理段 | |
STACK | 本段是堆栈的一部分,连接程序将所有STACK段按照与PUBLIC段的同样方式进行合并。 | 堆栈段必须具有该段组合 |
COMMON | 把该段和与该段名称相同的其他段重叠在一起形成一个重叠段(多个逻辑段拥有相同的段基值),重叠段的长度取决于其中最长逻辑段的长度。类似C的共用体。 | |
MEMORY | 表示该段的起始地址位于其他所有段的后面(在程序中位于最高内存地址一端)。 | 只有第一个被解释的MEMORY段作为MEMORY组合类型,后面的MEMORY段全部被解释为COMMON段 |
AT 表达式 | 使用这种类型可以自己定义段的起始地址 | 表达式的取值只能是16位二进制数,且低四位必须为0 |
类别:
ASSUME伪指令:指定各段和寄存器的关系,建立段寄存器与段的缺省关系。
ASSUME
伪指令可以重复使用,影响声明后的代码。ASSUME register_name:segment_name,...
例子
假设有ASSUME伪指令:
ASSUME DS:DATAS
则它告诉编译器,在以后使用 DATAS
段中定义的符号时,默认使用 DS
寄存器作为段地址。
MOV AX,逻辑段名
MOV 寄存器名,AX
offset
操作符取变量和标号相对于段组的偏移地址,如果没有段组则取得相对于段的偏移地址。offset
后可以跟段组中的某个段名,表示该段最后一个字节后面字节相对于段组的偏移地址。group_name GROUP segment1,segment2,...
例子
data1 segment word
const1 dw 100
data1 ends
data2 segment word
var1 dw ?
data2 ends
datagroup group data1,data2
若 ASSUME DS:datagroup
则:
MOV BX,offset data1
时,$BX=2$MOV BX,offset const1
时,$BX=0$MOV BX,offset data2
时,$BX=4$MOV BX,offset var1
时,$BX=2$NAME
作为模块名称TITLE
作为列表文件每一页上打印的标题,最大长度为60个字符NAME
,则text
前六个字符作为模块名TITLE
,则使用文件名作为模块名NAME module_name
TITLE text
.STARTUP
伪操作:产生程序开始执行的代码
.STARTUP
则源程序结束时不需要指定程序运行起点[LABEL]
用于指定程序运行的起点END [LABEL]
RET
进行结束code segment
main proc far
assume ……
start:
push ds
mov ax, 0
push ax
……
ret ; CS=DS,IP=0,此时会执行20H 中断指令
main endp
code ends
end start
code segment
assume ……
start:
……
……
mov ax,4c00h
int 21h
code ends
end start
.EXIT [返回参数]
[ 变量名 ] 大小标识 操作数项 [ ,操作数项,… … ]
大小标识 | 大小 |
---|---|
DB | 1B |
DW | 2B(字) |
DF | 3B |
DD | 4B(双字) |
DQ | 8B(四字) |
DT | 10B |
类型 | 解释 | 示例 |
---|---|---|
数字 | 为一个或连续的存储单元设置数值初值 | INT_VAR DB 13H |
字符串 | 必须用引号引起来,将字符串中的各字符均以ASCⅡ码形式存放在相应的存储单元 | STR_VAR DB 'HELLO WORLD$' |
带标识符的表达式 | 适用于 DW 和 DD 对于 DW,则存储偏移地址 对于 DD,则高位存储段地址,低位存储偏移地址 |
ADDR_VAR DW INT_VAR+2 将 INT_VAR 的偏移地址加2,赋值给 ADDR_VAR
|
? | 不赋初始值 | ADDR_VAR DW ? |
N DUP(初值,...) |
为连续的存储单元提供重复数据 N为重复次数 |
BUF DB 100 DUP (0) 定义一个大小为100个字节,初值为0的数据存储单元 |
例子
对于 数据 'AB'
:
若按照字节存储(数组):
MESSAGE DB 'AB'
其为数组类型,A
存入低字节,B
存入高字节。
其存储格式为:
高字节 | 低字节 |
---|---|
$42H$ | $41H$ |
若按照字存储:
MESSAGE DW 'AB'
其不为数组类型,则认为它是一个整体(同普通数字的存储),A
存入高字节,B
存入低字节。
其存储格式为:
高字节 | 低字节 |
---|---|
$41H$ | $42H$ |
例子
array db 1,2,3,4,5
db 6,7,8,9
db 0ah,0bh
EQU THIS
标识符 label 大小标识
标识符 EQU THIS 大小标识
例子
my_array label dw
array db 01H,02H,03H,04H
则 array
和 my_array
代表了同一片存储空间,但 array
是字节,my_array
是字。
expression_name EQU expression
例子
a equ var+4
mov ax,a
则 mov ax,a
汇编时变成 mov ax,var+4
。
符号名 = 表达式
$
的值不变例子
DATAS SEGMENT
A_VAR DB 1
B_VAR DW $,$+1,$+2
DATAS ENDS
则 B_VAR
开始的3个DW值为 1,2,3
EVEN
:使下一地址从偶地址开始ALIGN boundary
:从boundary的整数倍地址开始例子
DATAS SEGMENT
A_VAR DB 1
ORG 20H
B_VAR DW $,$+1,$+2
DATAS ENDS
A_VAR
的偏移地址为 0
,B_VAR
的偏移地址为 20H
,B_VAR
开始的3个DW值为 20H,21H,22H
.RADIX EXPRESSION
macro_name MACRO params1,params2,...
;code
ENDM
macro_name params1,params2,...
&
示例
; 宏定义
JUMP_MACRO MACRO CONDITION,FUNC
J&CONDITION FUNC
ENDM
; 宏调用
MOV AX,0
SUB AX, 0
JUMP_MACRO Z,TEST_FUNC
TEST_FUNC:
; some code
; 展开结果
MOV AX,0
SUB AX, 0
JZ TEST_FUNC
TEST_FUNC:
%
用于将表达式的值转换成当前基数下的数,而不是直接把表达式代入哑元示例
; 宏定义
TEST_MACRO MACRO NUM
MOV AX, NUM
ENDM
; 宏调用
CNTR = 0
TEST_MACRO % CNTR
CNTR = CNTR + 1
TEST_MACRO CNTR
CNTR = CNTR + 1
TEST_MACRO % CNTR
CNTR = CNTR + 1
; 宏展开结果
CNTR = 0
MOV AX, 0
CNTR = CNTR + 1
MOV AX, CNTR
CNTR = CNTR + 1
MOV AX, 2
CNTR = CNTR + 1
LOCAL SIGN1,SIGN2,...
LOCAL_MACRO MACRO CONDITION,FUNC
LOCAL MAR
MAR:
MOV AX, 0
ENDM
; 宏调用
LOCAL_MACRO
LOCAL_MACRO
LOCAL_MACRO
; 宏展开结果
??0000:
MOV AX, 0
??0001:
MOV AX, 0
??0002:
MOV AX, 0
.lst
中,宏如何展开的伪操作:伪操作 | 说明 |
---|---|
.XALL | (默认) 只展开代码,不展开单双分号注释 |
.SALL | 不列出任何展开信息 |
.LALL | 只展开代码,不展开双分号注释 |
;;
在任何时候都不展开;
在 .XALL
模式下展开.mac
或 .inc
结尾INCLUDE 路径
PURGE MACRO1,MACRO2,...
REPT expression
; CODE
ENDM
expression
的值将作为重复次数dummy
(哑元,同宏里面的哑元)IRP dummy,<argument1,argument2,argument3,...>
; CODE
ENDM
示例
; 重复定义
IRP X,<1,2,3,4,5,6>
MOV AX, X
ENDM
; 展开
MOV AX, 1
MOV AX, 2
MOV AX, 3
MOV AX, 4
MOV AX, 5
MOV AX, 6
dummy
(哑元,同宏里面的哑元)IRPC dummy,string
; CODE
ENDM
示例
; 重复定义
IRPC K,ABCD
MOV K&X, 0
ENDM
; 展开
MOV AX, 0
MOV BX, 0
MOV CX, 0
MOV DX, 0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。