汇编中的六大伪指令
指令:控制程序运行时的机器代码运作的,是CPU执行的依据,编程、编译、执行都是有效的。
伪指令: 伪指令不直接控制运行时刻的机器,但是控制翻译程序如何生成机器指令代码,也就是只为编译服务,编译完成后,伪指令的作用也就消失了。没有对应的机器代码,是由MASM汇编程序对源程序汇编期间进行处理的。
伪指令与指令的本质区别:汇编的过程中,伪指令并不形成任何代码,不直接命令CPU去执行什么操作。伪指令是给汇编程序的命令,在汇编过程中由汇编程序进行处理。如定义段等。
常用伪指令有6种:
-
标号赋值伪指令EQU:用来对一个标号赋值
eg:
ABC EQU 2400H ;使ABC为数值2400H
比较好理解,这里不作过多赘释 -
定义存储单元的伪指令DB、DW、DD、DQ、DT:
DB:字节
DW:字
DD:双字
DQ:4个字
DT:10个字伪指令DB和DW等用来给出程序中所需要的数据、字符串、地址表。该类伪指令用来为一个数据项分配存储单元,用一个符号名(变量名)与这个存储单元相联系,且为这个数据提供一个任选的初始值。
eg:DATA DB 24H,32H
表示从DATA地址单元开始,连续存入24H,32H,共占用2个字节的地址。
DATA DB ?,?
汇编程序分配两个字节单元,以DATA地址单元开始的两个单元可预置任何内容。
除了常数、表达式和字符外,问号“?”也可以作为数据定义伪指令的操作数。
此时仅给变量保留相应的存储单元,而不赋予变量某个确定的初值。 当同样的操作数重复多次时,可用重复操作符“DUP"表示.
格式:
n DUP(初值[,初值,…])其中圆括号中为重复的内容,n为重复次数。如果用"n DUP(?)"作为数据定义伪指令定义符的惟一操作数,则汇编程序产生一个相应的数据区,但不赋任何初值。重复操作符“DUP”可以嵌套。
eg:
FILLER DB ? (1)
SUM DW ? (2)
DB ?,?,? (3)
BUFFER DB 10 DUP(?) (4)
ZERO DW 30 DUP(0) (5)
MASK DB 5 DUP(‘OK!‘) (6)
ARRAY DB 100 DUP(3 DUP(8),6) (7)(1)、(2)分别给字节变量FILLER和字变量SUM分配存储单元,但不赋予特定的值。 (3)给一个没有名字的字节变量赋予3个不确定的值。 (4)给变量BUFFER分配10个字节的存储空间,但本赋任何初值。 (5)给变量ZERO分配一个数据区,共30个字(即60个字节),每个字的内容均为零。 (6)定义一个数据区, 其中有5个重复的字符串“OK!"。共占15个存储单元。 (7)为变最ARRAY定义一个数据区,其中包含重复100次的内容8,8,8,6,共占400个存储单元。
-
定义存储单元类型的伪指令BYTE、WORD、DWORD:对存储单元的类型进行规定
eg:
MOV BYTE PTR[DI ] ,00H (1)
MOV WORD PTR[1000H],00H (2)
JMP DWORD PTR[2000H] (3)(1)使DI所指的1个单元清0; (2)使1000H所指的1个字即2个单元清0: (3)使程序转移到另外一个段的某个单元,转移地址放在2000H开始的4个单元,前两个单元中的内容作为转移地址的偏移量,后面两个单元中的内容作为转移地址的段值
-
段定义伪指令SEGMENT、ENDS、ASSUME、ORG
SEGMENT和ENDS成对使用,用这一对伪指令可以将汇编语言源程序分成几个段,通常分为数据段、堆栈段和代码段。 ASSUME用来告诉汇编程序有关段寄存器与逻辑段的对应关系,哪一个段为数据段,哪一个段为堆栈段,哪一个段为代码段。并没有给段寄存器赋予实际的初值,真正将段地址装入段寄存器还需要由传送指令在执行时赋值。 ORG伪指令用来规定该伪指令后面的源程序或数据块存放的起始地址。
-
定义过程的伪指令PROC、ENDP
PROC和ENDP也是成对出现的,这两条伪指令之间的内容就作为一个过程,即一个子程序。
格式:
过程名 PROC [NEAR/FAR]
…
RET
过程名 ENDPROC伪指令定义一个过程(子程序),赋予过程一个名字,并指出该过程的属性为NEAR或FAR。如果没有特别指明类型,则认为过程的类型是NEAR。 如果对应的子程序头部标有FAR,则产生一个段间调用地址,它包括16位的段地址和16位的偏移量;如果子程序头部标有NEAR,则为段内调用。
当一个程序段被定义为过程后,程序中其他地方就可以用 CALL指令调用这个过程。
格式:
CALL 过程名 -
程序结束伪指令END
END是源程序的结束标志,该指令并不和其他伪指令成对使用。
汇编程序在对源程序进行汇编的过程中,遇到END,便得知源程序到此结束。
部分参考如下:
原文链接