汇编语言——伪指令详解 原创

2020-06-17 07:39:10 29点赞

Wilson Huang(三点羊羽) 

码龄4年关注

汇编语言的语句结构

1.1 标号名

1.1.1 定义:

标号(LABEL)是为一组机器指令所起的名字.标号可有可无,只有当需要用符号地址来访问该语句时,才给此语句赋予标号,以 : 作为结束符,其是指令的符号地址,代表了指令第一个字节地址。

1.1.2 作用:

标号是程序的目标标志,总是和某地址相联系,供转移或循环指令控制转移使用.

AGAIN: ...
	   ...
	   ...
JMP AGAIN

1.1.3 具有的属性:

(1)段属性:标号名所在段的段基址,标号段必须在CS中

(2)偏移地址属性:标号名所在段的偏移地址,单位是字节,是16位无符号整数

(3)距离属性:当其作为控制转移类指令的操作数时,可在段内或段间转移,这是距离属性不同

SHORT 距离在-128 ~ 127之间时称短标号

NEAR 段内标号,只允许在本段转移,近标号,距离在-32768 ~ 32767之间

FAR 段间标号,允许在段间转移

距离属性可用三种方法定义:

  • 隐含方式: 标号名后面跟 “ : ” ,隐含距离属性为NEARNEXT: ... ... ... LOOP NEXT
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4
  • 用伪指令LABEL定义距离属性格式:标号名 LABEL NEAR标号名 LABEL FARNEXT LABEL FAR ... ... ... LOOP NEXT
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5
  • 用EQU定义标号格式:标号名 EQU THIS NEARNEXT EQU THIS NEAR  ... ... ... LOOP NEXT
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

1.1.4 使用

  1. 无条件转移指令中标号作为转移地址格式: JMP 标号其中标号可以是短标号,近标号或远标号
  2. 循环指令中,标号作为转移地址格式:LOOP 标号其中标号只能是短标号
  3. 条件转移中标号作为转移地址格式:条件转移指令 标号其中标号只能用短标号
  4. 属性分离符
    • 取段地址算符SEGMOV AX,SEG NEXT ;SEG NEXT就是取标号NEXT所在段的段地址
      • 1
      • 1
    • 取偏移量算符OFFSETMOV BX,OFFSET NEXT ;其中OFFSET NEXT就是取标号NEXT的有效地址,该语句等效于:LEA BX,NEXT
      • 1
      • 1
    • 取类型算符TYPEMOV AX,TYPE NEXT ;若NEXT为近标号,则TYPE NEXT值为FFFFH(-1),若NEXT为远标号,TYPE NEXT值为FFFEH(-2).其中-1和-2 ;无真正的物理意义,仅以数值表示标号类型而已.
      • 1
      • 1

1.2 变量名

变量 (Variable) 代表存放在某些存储单元的数据,这些数据在程序运行期间可以随时被修改。变量是通过变量名在程序中引用,变量名实际上是存储区中一个数据区的名字,以变量名数据的方式供程序员使用,作为指令或伪指令的操作数,大大方便了程序设计者。

1.2.1 定义:

变量名是数据存储单元的符号地址,由汇编语言编译链接时为变量名分配存储单元,常作为一段数据区的符号地址,代表存储区域的第一个字节地址

1.2.2 具有的属性:

(1)段属性:标号名所在段的段基址

(2)偏移地址属性:标号名所在段的偏移地址

(3)类型属性:表示变量占用存储单元的字节数

类型属性存储单元字节数
BYTE1
WORD2
DWORD4
QWORD8
TBYTE10

1.3 操作码

1.3.1 指令助记符

指令助记符,是指令的关键部分,如MOV,AOD,SHL等指令

1.3.2 伪指令助记符

没有对应的指令操作码,主要用来定义变量,分配存储地址等,例如DB/DW/DD等\

1.4 操作数

操作数可以是常数、寄存器、标号、变量或表达式等。可有可无

分类:

  1. 无操作数
  2. 单操作数
  3. 双操作数:必须用逗号隔开

伪指令和宏指令允许有多个操作数

伪指令操作数:由操作符构成

1.5 注释字段(comment field)

分号隔开

MOV AX,BX ;这里是注释

2 数据定义伪指令

2.1 数据定义伪指令

通过数据定义语句可以为数据项分配存储单元,并设置初值。代表数据项的标识符称为变量名。

格式: [变量名] DB/DW/DD/DQ/DT 表达式 [注释]

伪指令助记符说明
DB定义字节型变量,每变量分配1个存储单元
DW定义字型变量,每变量分配2个存储单元
DD定义双字型变量,每变量分配4个存储单元
DQ定义四字型变量,每变量分配8个存储单元
DT定义十字型变量,每变量分配10个存储单元

分类:

2.1.1 数值表达式

表达式结果是确定的数值,用于初始化内存单元

DATA DB 24H
DATA2 DW 1234H+5678H

2.1.2 ?数据项

若定义的变量处置不确定可以用“?”表示,这是分配一个与类型匹配的存储单元,用于保留内存单元

DATA_A DB ?,20H
DATA_B DW 8543H,?

2.1.3 字符串

以ASCII码值得形式存放在存储区中,每个字符占据一个存储单元,可以用定义字节型变量的DB定义字符串,DW只可用来定义含有两个字符的字符串,字符串用单引号括起来,用于初始化内存单元。

STR1 DB 'MASM'
STR2 DW 'MY'

2.1.4 重复操作符

定义多个类型与初值相同的变量:

格式: [变量名] DB/DW/DD n DUP (表达式)

(1) n:变量重复次数,可为常数、字符和?

BUF2 DB 20 DUP (?) ;定义了20个不确定值的字节型变量

(2)DUP还可以嵌套使用

BUF2 DB 10 DUP (2, 2 DUP (3)) ;编译时分配30个存储单元给BUF2

2.2 运算符伪指令

2.2.0 常数

(1)二进制常数:以字母B结尾

(2)八进制常数:以字母Q结尾

(3)十六进制常数:以字母D结尾(可忽略)

(4)字符串常数:以ASCII码形式存放

2.2.1 算术运算符

(1)+:加

(2)-:减

(3)*:乘

(4)/:除、取整

(5)MOD:模除、取余

(6)SHL:左移

(7)SHR:右移

MOV AL, 16 MOD 5 ;(AL)=1
MOV AL, 10100100B SHR 2 ;(AL)=00101001B

2.2.2 逻辑运算符

(1)AND:与

(2)OR:或

(3)NOT:非

(4)XOR:异或

用于数值表达式中对数值进行按位逻辑运算,结果为8、16或32位二进制数

注意与逻辑运算指令的区别!!!: 逻辑运算符在汇编时就有汇编程序完成逻辑运算了,而逻辑指令是在指令执行的时候完成

;(DL)=10110100B
OR DL,NOT 7EH ;NOT 7EH在编译的时候数值已经确定为81H
;所以执行的时候等价为下面式子
OR DL,81H

2.2.3 关系运算符

(1)EQ 等于

(2)NE 不等于

(3)LT 小于

(4)GT 大于

(5)GE 大于等于

(6)LE 小于等于

参与关系运算的必须是两个数值,若关系成立,结果为真(0FFFFH),否则为假(0000H)

MOV AX,((12 LT 8) AND 5) OR ((20 GE 9) AND 7)
;(12 LT 8)=0000H,(12 LT 8) AND 5=0
;(20 GE 9)=0FFFFH,(20 GE 9) AND 7=7
;AX=0007H

2.2.4 分析运算符

SEGOFFSETTYPE加在变量名或标号名的前面

(1)SEG:得到变量名或标号名的段基址

(2)OFFSET:得到变量名或标号名的偏移量

(3)TYPE:在变量名前,返回值为1(字节)、2(字)、4(双字);在标号名前,返回值为-1(NEAR)、-2(FAR)

(4)LENGTH:用在变量前面,对于变量使用DUP进行定义的情况,汇编程序将回送分配给该变量的单元数。对于其他情况则回送1

(5)SIZE:用在变量前面,汇编程序将回送分配给该变量的字节数,值为 LENGTH 与 TYPE 值的乘积

3 属性说明伪指令

3.1 PTR操作符

格式: 类型 PTR 地址表达式

功能: 确定地址表达式的存储单元为指定的类型,即用在地址表达式之前,用于指定或临时改变变量名和标号名的类型

分类: BYTEWORDDWORDNEARFAR

例子:

ADD WORD PTR [SI],20  ;存储器操作数类型为字
JMP FAR PTR OK ;OK是可以进行段间转移的符号

3.2 THIS操作符

格式: THIS 类型

功能: 返回一个具有指定类型的存储器操作数。返回的存储器操作数地址的段基址和偏移地址就是下一个将要分配的存储单元的段基址和偏移地址。

例子:

MY_WORD EQU THIS WORD ;MY_WORD是一个字变量名,他的段基址和偏移地址与字节变量MY_BYTE相同
MY_BYTE DB ?  

3.3 SHORT (短转移说明)

格式: JMP SHORT PTR 目标地址

功能: 转移的目标地址等于当前IP的内容加上8位的位移量,转移的目标地址距离本条指令的下一条指令之间的偏移量范围为-128~127

3.4 LABEL伪指令

格式: 变量号/标号 LABEL [类型]

功能: 通常和下一个语句所定义的变量和标号联用,给下一个语句所定义的变量和标号取别名。别名由LABEL左边的名称决定,而其类型属性或距离属性则由LABEL右边的参数来给定。

分类:

  1. 与变量连用(改变其类型属性)TIMB LABEL BYTE ;为TIMW取别名TIMB,并修改类型为字节型 TIMW DW 1234H, 5678H ... ... ... MOV AX, TIMW[0] ;(AX)=1234H MOV BL, TIMB[0] ;(BX)=34H
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    定义堆栈段是也经常使用LABEL语句:ASTACK SEGMENT DW 20 DUP (?) TOP LABEL WORD ASTACK ENDS ;这里定义了一个由20字组成的堆栈,其栈底名称取名为TOP,类型定义为字
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4
  2. 与标号连用(改变其距离属性)SUBF LABEL FAR SUBN:MOV AX,[BX+SI];隐式定义了SUBN的距离属性为NEAR,前面为SUBN去了一个别名SUBF,属性为FAR。 ;SUBF和SUBN有着相同的逻辑地址,但他们的距离属性不同,可作为程序转移或调用时不同情况的入口,当段内转移或段间转移,调用不 ;同标号名称,实际上是指向同一条指令
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

4 伪指令的优先级

高低

序号运算符
1LENGTH/、SIZE、WIDTH、MASK、()、[]、<>
2PTR、OFFSET、SEG、TYPE、THIS
3HIGH、LOW
4*、/、MOD、SHL、SHR
5+、-
6EQ、NE、LT、LE、GT、GE
7NOT
8AND
9OR、XOR
10SHORT

建议使用圆括号

5 段定义与段分配伪指令

汇编语言的源程序分成若干个段:

  1. 数据段: 存放数据用
  2. 堆栈段: 保存信息用
  3. 程序段: 存放主程序用

5.1 段定义伪指令

5.1.1 段的基本属性

格式: (SEGMENT/ENDS伪指令)

段名 SEGMENT [定位类型] [组合类型] [字长选择] [类别名]
             ...
             (段体)
             ...
段名          ENDS

任何一个逻辑段从SEGMENT开始,以ENDS结束

段名:

  • 是赋予该段的一个名称,代表了该段的段地址
  • 程序中的段名可以是唯一的,也可以与其它段同名。在同一模块中,如果有二个段同名,则后者被认为是前段的后续,这样,它们就属同一段。
  • 当同一模块出现二个同名段时,则后者的可选项属性要么与前者相同,要么不写其属性而选用前者的段属性DATA1 SEGMENT        ;第一个数据段 MSG DB "Hello, " DATA1 ENDS CODE1 SEGMENT        ;第一个代码段 ASSUME CS:CODE1, DS:DATA1 START: MOV AX, DATA1 MOV DS, AX MOV DX, offset MSG MOV AH, 9 INT 21H CODE1 ENDS DATA1 SEGMENT        ;第二个数据段  DB "World.$" DATA1 ENDS CODE1 SEGMENT        ;第二个代码段 MOV AX, 4C00H INT 21H CODE1 ENDS END START END
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    在上面的例子中,第二个数据段是第一个数据段的后续,汇编程序把它们是合二为一,上述的代码段也如此。

5.1.2 定位类型、对齐类型(ALIGN)

其表示对段的起始边界的要求,连接程序(LINK.EXE)按下面列出的地址格式来定位段的起始地址。在进行段定位时,会根据其定位类型进行定位的,所以,各段之间就有可能出现一些空闲字节,即可能浪费几个字节单元。

  1. PAGE(页)表示本段从一页的边界开始,一页为256个字节,所以PAGE定义的边界的地址可以整除256,段的起始地址的后八位二进制数一定为0(即以00H结尾)
    • 段的起始位置为:XXXX XXXX XXXX 0000 0000B
    • 最多的空闲字节数:127
  2. PARA(节)表示本段从一节的边界开始,一节为16字节,段的起始地址的后四位二进制数一定为0(即以00H结尾)
    • 段的起始位置为: XXXX XXXX XXXX XXXX 0000B
    • 最多的空闲字节数:15
    • 段对齐类型PARA是一个适用于所有段类型的对齐类型,它也是缺省的对齐类型。
  3. DWORD(双字)表示本段的起始位置可以能被4整除。若用二进制表示后两位,则为00B
    • 段的起始位置为: XXXX XXXX XXXX XXXX XX00B
    • 最多的空闲字节数:3
    • 对齐类型DWORD通常用于80386及其以后CPU代码段的定位。
  4. WORD(字)表示本段从偶地址开始。若用二进制数表示,则该地址的最低位为0B
    • 段的起始位置为: XXXX XXXX XXXX XXXX XXX0B
    • 最多的空闲字节数:1
  5. BYTE(字节)表示本段可以从任何地址开始定位
    • 段的起始位置为: XXXX XXXX XXXX XXXX XXXXB
    • 最多的空闲字节数:0

对齐类型BYTE和WORD通常用于数据段的定位

5.1.3 组合类型

用来对各个逻辑段之间的连接方式提出要求,告诉连接程序如何把不同模块中段名相同的段合并在一起。具体的组合类型如下:

  1. NONE表示该段与其他同名段不进行连接,独立存于存储器中,如果语句中省略组合类型,则MASM把它作为NONE处理
  2. PUBLIC表示该段与其他模块中的同名段在满足定位类型的前提下由低地址到高地址连接起来,组成一个比较大的逻辑段
  3. COMMON表示当前段与其它模块中同名段重叠,也就是说,它们的起始地址相同,共享同一个存储区。最终段的长度是同名段的最大长度。由于段覆盖,所以,前一同名段中的初始化数据被后续段的初始数据覆盖掉。段的内容为所链接的最后一个模块中的内容及没有覆盖到的前面COMMON段的部分内容。
  4. MEMORY除了带有MEMORY参数的逻辑段覆盖在其他同名段的最高地址,与COMMON没其他区别
  5. STACK表示该段为堆栈段,其组合情况与PUBLIC相同。
  6. AT表达式该数值表达式是当前段所指定的绝对起始地址的段地址。表示本段可以定义在表达式所指示的节边界上。CODE SEGMENT AT 1200H ;表示该代码段段的起始位置为12000H,第一条指令从12005H处开始执行 ORG 0005H START: CODE ENDS
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

5.1.4 字长选择

用于定义段中使用的偏移地址和寄存器的字长,只用于设置32位微型计算机中语句的段

  1. USE16偏移地址为16位,段内最大寻址空间为64KB
  2. USE32偏移地址为32位,段内最大寻址空间为4GB

5.1.5 类别(CLASS)

类别是一个由程序员指定的用单引号括起来的字符串,用于连接时决定各逻辑段被装入的顺序,即具有相同类别名额逻辑段按出现的先后顺序被装入连续的内存中。如果一个段没有给出类别,那么,这个段的类别就为空。类别是用于段的分类,连接程序利用该类别来调整同名、同类别的段,并使它们相邻。典型的类别是”Data”和”Code”。如果指定某段的类别是”Code”,那么,该段最好是代码段,这样,有的调试程序(如:CodeView)就可以顺序工作。

DATA1 SEGMENT  WORD  PUBLIC  "Data"
…
DATA1 ENDS

上述段定义说明了该段的起始地址是下一个字地址、组合类型为PUBLIC、段类别是”Data”。

5.2 段分配伪指令

ASSUME伪指令来指明各段。放在代码段内,放在段定义语句之后

格式: ASSUME 段寄存器名:段名[,段寄存器名:段名, ...]

ASSUME CS: CODE, DS: DATA, SS:STACK

段分配语句只建立当前段和段寄存器之间的联系,但段分配语句并不能将各段的段基址装入各个段寄存器。段基址的装入需要用程序额的方法,而且6个段寄存器的装入也不尽相同。

段组:

段组伪指令GROUP是用于把源程序模块中若干个段结合成一个组,并对该段组定义一个段组名。段组伪指令的格式如下:

段组名 GROUP 段名[, 段名, ……]

其中:段名之间要用逗号间隔,段名也可以用表达式“SEG 变量”或“SEG 标号”。

举例:方法1:用一个段寄存器对应二个数据段

DATA1	SEGMENT	;第一个数据段
        b1	DB 10h
DATA1	ENDS
DATA2	SEGMENT	;第二个数据段
        b2	DB 23h
DATA2	ENDS
CODE1	SEGMENT
		ASSUME CS:CODE1, DS:DATA1	;(1)
		MOV	AX, DATA1
        MOV	DS, AX 	;(2)把数据段DATA1的段值赋给段寄存器DS
        ...
        MOV	BL, b1	;(3)引用DS来访问DATA1中的变量b1
        ...
START:	ASSUME DS:DATA2	;(4)
        MOV	AX, DATA2
        MOV	DS, AX	;(5)把数据段DATA2的段值赋给段寄存器DS
        ...
        MOV	AL, b2	;(6)引用DS来访问DATA2中的变量b2
        ...
CODE1	ENDS
		END	START

在上例中,语句(1)说明DS与DATA1建立联系,语句(2)对DS赋值,语句(3)用DS来访问DATA1段的变量名。语句(4)说明DS与DATA2建立联系,语句(5)对DS赋值,语句(6)用DS来访问DATA2段的变量名。

在该例子中,因为只使用一个段寄存器DS来对应二个数据段,所以,需要切换DS的对应关系(如:语句(4))。但我们也可以用段寄存器DS和ES来分别对应段DATA1和DATA2,这样,方法1就可变成方法2。

方法2:用二个段寄存器对应二个数据段

DATA1	SEGMENT
		b1	DB 10h
DATA1	ENDS
DATA2	SEGMENT
		b2	DB 23h
DATA2	ENDS
CODE1	SEGMENT
		ASSUME CS:CODE1, DS:DATA1, ES:DATA2
START:	MOV	AX, DATA1
		MOV	DS, AX 	;把数据段DATA1的段值赋给段寄存器DS
		MOV	AX, DATA2
		MOV	ES, AX	;把数据段DATA2的段值赋给段寄存器ES
		...
		MOV	BL, b1	;引用DS来访问DATA1中的变量b1
        ...
        MOV	AL, b2	;引用ES来访问DATA2中的变量b2
        ...
CODE1	ENDS
		END	START

我们还可以用段组来简化段寄存器的使用,把段DATA1和DATA2组成一个数据段。所以,把方法2再改写成方法3的形式。

方法3:用一个段组组成二个数据段

GSEG	GROUP	DATA1, DATA2	;把段DATA1和DATA2定义成一个段组
DATA1	SEGMENT
 		b1	DB 10h
DATA1	ENDS
DATA2	SEGMENT
		b2	DB 23h
DATA2	ENDS
CODE1	SEGMENT
		ASSUME CS:CODE1, DS:GSEG
START:	MOV	AX, GSEG
		MOV	DS, AX 	;把段组GSEG的段值赋给段寄存器DS
		...
		MOV	BL, b1	;引用DS来访问DATA1中的变量b1
		...
		MOV	AL, b2	;引用DS来访问DATA2中的变量b2
		...
CODE1	ENDS
		END	START

定义段组后,段组内各段所定义的标号和变量,除了与定义它们的段起始点相关外,还与段组的起始点相关。规定如下:

  • 如果在ASSUME伪指令中说明段组与段寄存器相对应,那么,有关标号或变量的偏移量就相对于段组起点计算;
  • 如果在ASSUME伪指令中说明段组内的某各段与段寄存器相对应,那么,有关标号或变量的偏移量就相对于该段的起点。

所以,在使用段组后,程序员要谨慎使用ASSUME伪指令,并保证段寄存器的值与段组或段相一致。

6 赋值伪指令

6.1 表达式赋值伪指令(EQU)

表达式赋值伪指令为常量、变量、表达式或其他符号定义一个新的名字,但不分配内存空间

格式: 符号名 EQU 表达式

表达式可以是常数、数值表达式、地址表达式、变量、标号或指令助记符

(1)表达式中,变量名及标号名必须在伪指令前定义

(2)在同一程序段中,不允许同一个变量名重新定义

NUM EQU 2*4 				;NUM代表常数8
COUNT EQU 4*NUM 			;已定义的符号常数可以用于表达式
STRING1 EQU 'HELLO WORLD!'  ;用符号表示一个字符串
MOVE EQU MOV                ;重新定义指令助记符

6.2 等号伪指令

可以用来定义符号常数,等号语句定义的符号名允许重新定义。

格式: 符号名=数值表达式

7 地址定义伪指令

7.1 地址计数器($)

为了指示程序中指令或数据在相应段中的偏移地址,可使用地址定位伪指令和当前地址计数器

$表示地址计数器的值。地址计数器保存当前正在汇编的指令或数据的偏移地址。汇编程序每扫描一个字节,地址计数器的值加1

例如:

JMP $

程序跳转到本条指令,即进入死循环状态。该语句一般用于等待中断的发生。

再如:

DATA SEGMENT
  ARRAY DB 'PROGRAM'
        NUM EQU $-ARRAY ;$表示当前指令的偏移地址值,ARRAY是变量名,表示变量ARRAY的偏移地址值,$-ARRAY是以变量ARRAY为其			               ;值地址的连续字节数,即变量名为ARRAY的字符串的字符个数
DATA ENDS

7.2 定位伪指令(ORG)

格式: ORG 数值表达式

作用: 用于调整地址计数器的当前值,数值表达式则会给出偏移地址的值。当对该语句进行汇编的时候,将地址计数器的值调整成数值表达式的结果,表达式运算的结果必须是正整数,并且以65535为模。

     ORG 0100H
BEGIN: MOV AL, 15H
	 ORG 0500H
NUM DW 7890H

标号BEGIN的偏移地址是0100H,变量NUM的偏移地址为0500H

8 过程定义伪指令

过程——子程序(可被程序调用),汇编语言规定必须对过程进行定义。过程定义之后就可对(调用指令CALL)和(返回指令RET)进行正确的汇编。

如果过程中要用到某些寄存器或存储单元,为了不破坏原有的信息,要将寄存器或存储单元的原有内容压栈保护或存入子程序不用的寄存器或存储单元中。起保护作用的程序段可以放在主程序中,亦可以放在子程序中。

过程定义语句的格式为:

过程名 PROC NEAR/FAR
	  语句
	  ...
	  RET ;过程的最后一条执行指令,。将堆栈内保存的返回地址弹出,以实现程序的正确返回
过程名 ENDP
  • NEAR(近过程): 该过程与调用指令CALL处在同一代码段中(段名相同),只需将返回未知的偏移地址压入堆栈
  • FAR(远过程): 该过程与调用指令CALL处在不同代码段中(段名不同),需将返回未知的偏移地址和段基址都压入堆栈
CODE SEGMENT PARA PUBLIC 'CODE'
  ASSUME CS: CODE, DS: DATA, SS: STACK
  SUBB1 PROC NEAR/FAR
        语句
        ...
        RET
  SUBB1 ENDP
START:
  CALL SUBB1
  ...
  CALL SUBB1
  ...
CODE ENDS
  END START

9 程序模块命名与程序结束伪指令

  1. NAME/END伪指令用于定义一个模块。在链接目标模块时将使用该模块名,汇编处理只进行到模块结束语句为止格式:NAME 模块名 ... END 标号
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3
  2. PUBLIC伪指令用来说明已知模块中哪些标识符是公共的,可以被其他模块引用。格式: PUBLIC 符号符号可以是本模块已定义的变量、标号、变量名、过程名等
  3. EXTERN伪指令用于说明模块中哪些标识符是外部的,即其他模块中已被PUBLIC伪指令说明的符号格式: EXTERN 符号名:类型[,符号名: 类型··· ]
  4. END伪指令一个程序模块只允许有一个END语句,后为主模块其实地址格式: END [起始地址标号]汇编程序将起始地址标号的段基址和偏移地址赋给当前的CS、IP

打开CSDN,阅读体验更佳

8086汇编伪指令大全详解

初学者必备的资料,详细的介绍了汇编中涉及的所有伪指令

汇编常用伪指令

汇编常用伪指令评论(1) 请先 登录 后发表或查看评论

伪指令_qq_41386300的博客_伪指令

1. 数据定义伪指令 数据定义伪指令助记符 例: 上例变量在内存中的分布: 说明 重复操作符 常用于声明一个数据区 n是重复的次数 例: 上例:定义了一个以M1为首地址的10个字节的单元,每个单元中的初始值都是0 …

汇编伪指令_strikeshine的博客_伪指令

段定义伪指令 段定义伪指令是表示一个段开始和结束的命令,80×86有两种段定义的方式:完整段定义和简化段定义,分别使用不同的段定义伪指令来表示各种段。 1 完整的段定义伪指令 完整段定义伪指令的格式如下: 段名 SEGMENT . . .

热门推荐 汇编语言中常用的伪指令

汇编语言中,指令语句在源程序汇编时会产生可供计算机执行的指令代码,即目标代码。汇编程序除指令语句外,还需要提供一些指令,用于辅助源程序的汇编。比如指定程序或数据存放的起始地址,为数据分配一段连续的内存单元等。这些指令汇编时并不生成目标代码,不影响程序执行,因此称之为伪指令。本文简单总结了常用的伪指令,如下。 1、EQU(Equate) 一般格式为:  标号:         EQU浏览器打开

汇编伪指令

唐长老GNU汇编伪指令集GNU汇编器的平台无关伪指令如何插入一段漂亮的代码片功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出…浏览器打开

[汇编]伪指令(一)_superfatsheep的博客

[汇编]伪指令(一) 段定义伪指令 段定义伪指令是表示一个段开始和结束的命令,80×86有两种段定义的方式:完整段定义和简化段定义,分别使用不同的段定义伪指令来表示各种段。 1 完整的段定义伪指令 完整段定义伪指令的格式如下: 段名…

ARM汇编伪指令_txwang2008的专栏

ARM 汇编程序的由机器指令,伪指令和宏指令组成。伪指令不像机器指令那样在处理器运行期间由机器执行,而是汇编程序对源程序汇编期间由汇编程序处理。在前面的指令集章节中,我们已经接触了几条常用到的伪指令,如ADR 、ADRL、LDR、NOP 等,…

指令伪指令的区别

    这个标题看似简单,但是我却一下子没明白,这里做下记录。    指令:每一条指令语句在源程序汇编时都要产生可供计算机执行的指令代码(即目标代码),所以这种语句又叫做可执行语句,每一条指令语句表示CPU具有的一个基本能力,比如数据传送,两数相加或相减,移位等,而这种能力是在目标程序运行时完成的,是依赖于CPU、存储器、IO等接口设备来实现的。    伪指令:顾名思义,它不是真正的指令,也就是不…浏览器打开

[汇编]伪指令

段定义伪指令   段定义伪指令是表示一个段开始和结束的命令,80×86有两种段定义的方式:完整段定义和简化段定义,分别使用不同的段定义伪指令来表示各种段。  1 完整的段定义伪指令  完整段定义伪指令的格式如下:  段名 SEGMENT    .    .    .  段名 ENDS  段名由用户命名。对于数据段、附加段和堆栈段来说,段内一般是存储单元的定义、分配等伪指令语句…浏览器打开

汇编语言中常用的伪指令_forge1yc的博客_汇编伪指令

汇编语言中常用的伪指令 汇编语言中,指令语句在源程序汇编时会产生可供计算机执行的指令代码,即目标代码。汇编程序除指令语句外,还需要提供一些指令,用于辅助源程序的汇编。比如指定程序或数据存放的起始地址,为数据分配一段连续的内存单元…

汇编常见伪指令_zhy05的博客_汇编伪指令

在宏定义时,为了满足某种特殊需要,汇编语言还提供了几个伪指令。 9.3.1 局部标号伪指令LOCAL 在宏定义体中,如果存在标号,则该标号要用伪指令LOCAL说明为局部标号,否则,当在源程序中,有多于一次引用该宏时,汇编程序在进行宏扩展后将会…

linux汇编伪指令大全,ARM汇编伪指令

分类: LINUX2009-10-21 16:39:09ARM 汇编程序的由机器指令伪指令和宏指令组成。伪指令不像机器指令那样在处理器运行期间由机器执行,而是汇编程序对源程序汇编期间由汇编程序处理。在前面的指令集章节中,我们已经接触了几条常用到的伪指令,如ADR 、ADRL、LDR、NOP 等,把它们和指令集一起介绍是因为它们在汇编时会被合适的机器指令代替,实现真正机器指令操作。宏是一段独立的程…浏览器打开

ARM汇编伪指令介绍

在 ARM 汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。          在 ARM 的汇编程序中,有如下几种伪指令:符号定义伪指令、数据定义伪指令汇编控制伪指令浏览器打开

汇编伪指令的学习_天糊土的博客

(1)伪指令不是指令,伪指令指令的根本区别是经过编译后会不会生成机器码。 (2)伪指令的意义在于指导编译过程。 (3)伪指令是和具体的编译器相关的,我们使用gnu工具链,因此学习gnu环境下的汇编伪指令

伪指令及其作用_bird67的博客_伪指令的作用

伪指令是相对标准指令而言的,高级语言不存在伪指令,因为高级语言不存在指令,很难说明高级语言中哪一条语句是什么指令。 伪指令是为程序开发工程师提供辅助的程序表达,让编译器实现一些标准指令所不能表达的内容。

常见汇编代码

常见汇编代码 编写程序:比较AX,BX,CX中带符号数的大小,将最大的数放在AX中code segment assume cs:code mov ax,32 mov bx,74 mov cx,23sort: cmp ax,bx jge X ;如果ax大于等于bx就跟cx比较 xchg ax,bx X:cmp ax,cx ;如果浏览器打开

汇编中的伪指令

汇编中的伪指令什么是伪指令?一些常用的伪指令ASSUMEsegment……endsend 什么是伪指令? 伪指令(Pseudo Instruction)是用于对汇编过程进行控制的指令,该类指令并不是可执行指令,没有机器代码,只用于汇编过程中为汇编程序提供汇编信息。例如,提供如下信息:哪些是指令、哪些是数据及数据的字长、程序的起始地址和结束地址等。伪指令有2个特点: (1)由于是伪“指令”,因而它只存在于汇编语言中。高级语言中不叫指令,叫语句; (2)由于是“伪”指令,也即“假”指令,因而不是可执行指令,不会浏览器打开

汇编指令大全

汇编指令大全 MOV—-> move MOV dest,src ;dest←src MOV指令把一个字节或字的操作数从源地址src传送至目的地址dest。 MOVSX—->extended move with sign data MOVZX—->extended move with zero data PUSH—->push POP—->pop 进栈出栈指令PUSHA—->push all POPA—->pop al…浏览器打开

最新发布 8086汇编语言(二) 汇编语言伪指令

汇编语言伪指令   指示性语句中的位操作命令, 称为伪指令 1. 数据定义伪指令 (1). 格式 [变量名] 位操作 操作数1, 操作数2 … 定义数据伪操作有以下五种 伪操作 作用 变量占据内存 DB 定义变量为字节类型 8位 DW 定义变量为字类型 16位 DD 定义变量为双字类型 32位 DQ 定义变量为四字类型 64位 DT 定义变量为十字街类型 80位 (2). 操作数   数据定义伪操作后的操作数可以是常数、表达式或字符串 举例 DATA DB 21H,浏览器打开

汇编中的六大伪指令

指令:控制程序运行时的机器代码运作的,是CPU执行的依据,编程、编译、执行都是有效的。 伪指令: 伪指令不直接控制运行时刻的机器,但是控制翻译程序如何生成机器指令代码,也就是只为编译服务,编译完成后,伪指令的作用也就消失了。没有对应的机器代码,是由MASM汇编程序对源程序汇编期间进行处理的。 伪指令指令的本质区别:汇编的过程中,伪指令并不形成任何代码,不直接命令CPU去执行什么操作。伪指令是给…浏览器打开

汇编伪指令

伪指令语句:(指示性语句)在汇编时被解释执行,由汇编程序来处理的一类操作。 伪指令的格式 格式:符号名 定义符 操作数; 注释 常用伪指令 1、符号定义伪指令(赋值语句) (1)等值伪指令 格式:符号名 EQU 表达式 (EQU定义不占用内存单元) 功能:将表达式的值赋给符号名。 注意:符号名一旦被EQU定义,就不能再赋值,即不能用EQU再为符号名重新赋值。 (2)等号伪指令 格式:符号名 = 表达式…浏览器打开

ARM汇编指令

一. 带点的(一般都是ARM GNU伪汇编指令)   1. “.text”、”.data”、”.bss” 依次表示的是 “以下是代码段”, “以下是初始化数据段”, “以下是未初始化数据段”。 2.”.global” 定义一个全局符号,通常是为ld使用。比如经常看到的 .global _start 3.”.ascii”、”.byte”、”.short&浏览器打开

汇编语言伪指令

1、伪指令语句 伪指令语句是给汇编程序的命令,在汇编过程中由汇编程序进行处理,如定义数据、发配存储区、定义段以及过程等。不产生目标代码。 1、符号定义伪指令(1)EQU(赋值伪指令) (2)=(等号伪指令) (3)LABEL(类型定义伪指令) 2、数据定义伪指令 1)DB 定义变量为字节(BYTE)类型,占一个单元 2)DW 定义变量为字(WORD)类型,占2个单元 3)DD 定义变量为双字(…浏览器打开

汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp这些都是什么意思啊?

 eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。比方说:add eax,-2 ;   //可以认为是给变量eax加上-2这样的一个值。这些32位寄存器有多种用途,但每一个都有“专长”,有各自的特别之处。EAX 是”累加器”(accum浏览器打开

常用伪指令

汇编语言中,指令语句在源程序汇编时会产生可供计算机执行的指令代码,即目标代码。汇编程序除指令语句外,还需要提供一些指令,用于辅助源程序的汇编。比如指定程序或数据存放的起始地址,为数据分配一段连续的内存单元等。这些指令汇编时并不生成目标代码,不影响程序执行,因此称之为伪指令。本文简单总结了常用的伪指令,如下。 1、EQU(Equate) 一般格式为: 标号: EQU 操作数指令功能为将操作数赋予标号,两边的值完全相等。使用EQU伪指令给一个标号赋值后,此标号在整个源文件浏览器打开伪指令汇编伪指令大全写评论112729

类似文章