【Chapter4】汇编语言及其程序设计,《微机系统》第一版,赵宏伟

一、汇编语言概述

**指令:**指使计算机完成某种操作的命令。

**程序:**完成某种功能的指令序列。

**软件:**各种程序总称。

**机器语言:**计算机能直接识别的语言。用机器语言写出的程序称为机器代码。

**汇编语言:**用字符记号代替机器指令。用汇编语言编写的程序叫汇编语言源程序。

**汇编程序:**一种翻译程序,把助记符翻译成机器语言

在计算机上运行汇编语言程序的步骤:

二、汇编语言语句格式

汇编语句格式有4个字段:

c 复制代码
[名字]	操作符	操作数;	[注释]

[名字]:

  1. 一种标识符

  2. **组成:**A~Z,a~z,0~9;专用符号 ? . @ _ $

  3. 限制:

    1. 第一个字符不能是数字
    2. "." 必须是第一个字符
    3. 前31个字符有效
    4. 不能为关键字
  4. **类型:**标号-指令符号地址

    ​ 变量-数据符号地址

操作符:

  • **组成:**CPU指令、伪指令、宏指令

[注释]:

  • 说明程序、指令的功能,增加程序的可读性

三、指令格式

一条指令由五部分 组成:前缀、操作码、{寻址方式、偏移量、立即数}(操作数)

3.1 前缀

**前缀:**是对指令的某种限定或说明。可分为下面四种:

  1. **指令前缀:**说明指令的相关特性。如LOCK、REP、REPE/REPZ、REPNE/REPNZ
  2. 段超越前缀:用超越段取代默认段。三种情况禁止段超越串操作(ES)、堆栈指令(SS)、代码段(CS)
  3. **操作数大小前缀:**改变默认的数据长度。16→32,32→16。
  4. **地址大小前缀:**改变默认的地址长度。
  • 在实地址、虚拟8086方式下,隐含寻址16位。
  • 在保护方式下,隐含寻址由段描述符中的D位确定,D = 0默认是16位,D = 1默认是32位
  • 指令前缀段超越前缀用于改变显式特性,2选1,由编程人员编写
  • 操作数大小前缀地址大小前缀用于改变隐式特性,可共存,由汇编程序自动加入。

3.2 操作码

**操作码:**规定了微处理器执行的操作,如加、减、传送等。

Pentium 微处理器指令的操作码长为1或2个字节 。第一个字节的前6位是操作码 ,其余两位中的D位用来指示数据流的方向W位用来指示数据的长度是字节还是字或双字。

  • D=1,R/M -> REG
  • D=0,REG-> R/M
  • W = 1,字,或双字
  • W = 0,字节

3.3 寻址方式

**寻址方式:**用来指出CPU获取操作数的方式,如寄存器寻址、直接寻址、寄存器间接寻址等。

(1)MOD域

MOD域:规定所选指令的寻址方式 ,选择寻址类型 及所选的类型是否有位移量

MOD域 共2位4种组合含义如下:

(2)REG域 & MOD = 11下 的R/M域

REG域或者MOD=11时表示R/M选中R三位代码组合的8种情况的含义如下:

++其实就是4个数据寄存器和4个指针和变址寄存器++

++在W 指示 数据长度为 字节、字、双字时分别表示寄存器使用8、16、32位++

(3)R/M域

MOD != 11时,表示用于存储器寻址

其含义如下:

  • MOD = 00、01、11分别表示:无偏移量、8位偏移量、16位偏移量
  • 表格中每一项上下分别表示:段内偏移 和 寻址方式的隐含段

3.4 位/偏移量及立即数

**位/偏移量:**允许指令中直接给出寻址方式所需的位/偏移量。

**偏移量: ** 直接寻址 的地址,无符号数,如 MOV AX,[2000H]

位移量: 相对寻址 中的地址数据,有符号数,如 MOV AX,[SI+6]

立即数:允许指令中直接给出操作数。

四、寻址方式

一条汇编指令要解决2个问题:

  1. 做什么
  2. 对象,或对象来源,即寻址方式

**寻址方式掌握要点:**侧重理解操作数的寻址过程,如何找到一个操作数。

有2类寻址:

  1. 对操作数寻址
  2. 对转移地址、调用地址寻址

4.1 数据的寻址方式

Pentium系统中使用字节(8位)、字(16位)、双字(32位)和4倍字(64位)。采用低端存储方式。

与数据有关的寻址方式有11种:

  1. 立即数寻址
  2. 寄存器寻址
  3. 存储器寻址
    1. 直接寻址
    2. 寄存器间接寻址
    3. 寄存器相对寻址
    4. 基址变址寻址
    5. 相对基址变址寻址
    6. 比例变址寻址
    7. 相对比例变址寻址
    8. 基址比例变址寻址
    9. 相对基址比例变址寻址

4.1.1 立即寻址

**立即寻址:**操作数是指令的一部分。完整地取出该条指令之后也就获得了操作数。这种操作数称为立即数。

主要用于对寄存器赋值,速度快。

汇编语言规定: 立即数 必须以数字开头 ,以字母开头的十六进制数 前必须以数字0做前缀数制用后缀表示 ,(B 表示二进制数,H 表示十六进制数,(D 或者缺省表示十进制数,Q表示八进制数,程序员可以用自己习惯的计数制书写立即数。汇编程序在汇编时,对于不同进制的立即数一律汇编成等值的二进制数,有符号数以补码表示。

此外,立即数还可以是用+、-、x、/ 表示的算术表达式。汇编程序按照先乘除后加减的规则自动计算,也可以用圆括号改变运算顺序。

立即寻址的例子

c 复制代码
MOV AL, 01010101B
MOV BX, 1234H
MOV EAX, 12315678H

4.1.2 寄存器寻址

**寄存器寻址:**操作数在CPU的某个寄存器中,指令指定寄存器号。

寄存器寻址是最通用的数据寻址方式。对于8位操作数,寄存器有AH、AL、BH、BL、CH、CL、DH和DL;对于16位操作数,寄存器可以是AX、BX、CX、DX、SP、BP、SI和DI;在80386以上的微处理器中,还可以是32位操作数,寄存器有EAX、EBX、ECX、EDX、ESP、EBP、EDI和ESI。

有些用寄存器寻址的MOV、PUSH和POP指令可寻址16位的段寄存器(CS、ES、DS、SS、FS和GS)。

寄存器寻址的例子:

C 复制代码
MOV DS, AX
MOV EAX, ECX
MOV DL, BH

4.1.3 存储器寻址

**存储器寻址:**操作数在存储器中

存储器地址:

  • 物理地址
  • 逻辑地址: 段基址:偏移量

CPU要访问存储器操作数,必须先计算存储器的物理地址。

在实地址和保护方式下,段基址的获取方式不同,但偏移量的获取思想基本一致。

在存储器寻址方式中,要解决的问题是如何取得操作数的偏移地址。

有效地址EA:Effective Address,在8086~Pentium微处理器里,把操作数的偏移地址称为有效地址EA。

有效地址的计算
E A = 基址 + ( 变址 × 比例因子 ) + 位移量 EA = 基址 + (变址\times 比例因子) + 位移量 EA=基址+(变址×比例因子)+位移量
基址:基址寄存器中的内容。基址寄存器通常用于编译程序指向局部变数据段中数组或字符串的首地址

变址:变址寄存器中的内容。变址寄存器用于访问 数组或字符串的元素

**比例因子:**32位机的寻址方式。寻址中,用变址寄存器的内容乘以比例因子得到变址值。该方式对访问数组特别有用。(就类比c语言,字符指针+1是移动1个字节,int指针是4个字节,这里的比例因子就起到类似作用,为1就是一次8位,2就是一次16位)

**位移量:**指令中的一个数,但不是立即数,而是一个地址。

8086/286是16位寻址,80386及以后机型是32位寻址,也可用16位寻址。

9种存储器寻址方式

如下表:(星号代表二者选一个)

我们发现相对寻址都是带位移量的,比例寻址都是带比例因子的

存储器寻址举例

如下表:

  • 我们汇编指令中,用"[]"括起来的操作数代表EA
  • 由于我们处理器是分页存储,我们还需要知道段基址 ,前面提过了指令格式中的寻址方式是有隐含段

寻址方式的段约定和段超越

我们描述段超越的方式就是:在间址前面加上段名加":"

下面是一些示例:

c 复制代码
MOV AL, DS: [BP]	; 用BP间址访问数据段
MOV AL, ES: [BP]	; 用BP间址访问ES附加段
MOV AL, FS: [EBP]	; 用EBP间址访问FS附加段
MOV AL, CS: [BX]	; 用BX间址访问代码段
MOV AL, ES: [SI+5]	; 用SI变址寻址,访问ES附加段
MOV AL, GS: [EAX+10] ; 用EAX基址寻址,访问GS附加段

为提高程序的可读性和效率,要尽量少使用段超越

各存储器操作类型的隐含段、可使用超越段、段内偏移量描述如下:

4.2 转移地址的寻址方式

**转移地址寻址:**用于确定转移指令和CALL指令的转向地址。

转移指令使程序不再顺序执行,而是按指令中给出的操作数转移到相应的目的地址。

转移地址:转移指令中的操作数是转移的目的地址,称为转移地址。

转移指令调用指令分为:

  • 段内(IP/EIP)转移
    • 直接(相对)转移
    • 间接
  • 段间(CS:IP/EIP)转移
    • 直接
    • 间接

4.2.1 段内相对寻址

(位移量+IP = EA)→IP/EIP,即把有效地址EA送给IP/EIP

位移量是相对值,所以称为段内相对寻址。

因为是相对值,所以便于程序再定位。

用于条件转移、无条件转移,条件转移只能用此方式。

**短跳转:**JMP SHORT AA9 ;位移量 8位,-128 ~ +127

**近跳转:**JMP NEAR PTR AA8 ;位移量 16位 ± 32K,32位 ± 2G

4.2.2 段内间接寻址

  • 寄存器(存储器)内容 = EA→IP/EIP
  • 这种寻址方式不能用于条件转移指令。
  • JMP BX
  • JMP WORD PTR[BX + AA7]
  • JMP ECX

4.2.3 段间直接寻址

指令给出一个逻辑地址,段地址送给CS,段内偏移送给IP或EIP

  • 目标段地址:偏移量 = CS:IP/EIP
  • JMP FAR PTR AA6

4.2.4 段间间接寻址

  • 连续的存储器单元内容 = CS:IP/EIP
  • JMP DWORD PTR [SI];[SI]指向的字送入IP,[SI + 2]指向的字送入CS。

4.3 堆栈地址寻址

**堆栈:**以"先进后出"方式工作的一个特定的存储区。

一端固定,称为栈底;另一端浮动,称为栈顶,只有一个出入口。

**堆栈作用:**保存传递参数、现场参数、寄存器内容、返回地址。

80x86规定:

  1. 堆栈向小地址方向增长。
  2. 必须使用堆栈段SS。
  3. PUSH 指令压入数据时,先修改指针 按照指针指示的单元存入数据。
  4. POP 指令弹出数据时, 按照指针指示的单元取出数据再修改指针
  5. 压入和弹出的数据类型(数据长度)不同,堆指针修改的数值也不同。

16位堆栈地址操作,还是32位堆栈地址操作,由堆栈段SS寄存器内的数提段描述符的属性说明,确定用SP还是ESD,是一种隐含属性。

五、指令系统

**指令系统:**指令的集合。软硬件交界面。

**指令系统掌握要点:**侧重掌握指令的功能和使用方法,为后续程序设计打基础。

  • 8086-110条指令
  • 80286-143条指令
  • 80386-154条指令
  • 80486-160条指令
  • Pentium - 165条指令

Pentium指令系统按功能分为10类:

数据传送指令、算术运算指令、BCD码调整指令、逻辑运算指令、位处理指令、控制转移指令、条件设置指令、串操作指令、处理器控制

指令、保护模式系统控制指令。

5.1 数据传送指令

**数据传送指令功能:**源 -> 目

指令执行后,源操作数不变,不影响状态标志

5.1.1 MOV 传送(move)

c 复制代码
格式:MOV DST, SRC	;	(DST) <- (SRC)

源、目长度相等。CS可出不可入

MOV WORD PTR[BX], 10H;立即数10H送入BX指向的字存储单元

数据间传输关系如下:

5.1.2 PUSH进栈指令

c 复制代码
格式:PUSH SRC	; 堆栈 <- (SRC)

操作:

  • 16位指令:(SP) <- (SP - 2), ((SP) + 1, (SP)) <= (SRC)
  • 32位指令:(ESP) <- (ESP - 4), ((ESP) + 3, (ESP) + 2, (ESP) + 1, ESP) <- (SRC)

类型:

5.1.3 POP出栈(pop from the stack)

c 复制代码
格式:POP DST	; (DST) <- 堆栈栈顶内容

操作:

  • 16位指令:(DST) <- (SP + 1, SP), (SP) <- (SP + 2)
  • 32位指令:(DST) <- (ESP + 3, ESP + 2, ESP + 1, ESP), (ESP) <- (ESP + 4)

类型:

堆栈指令举例:

MOV AX, 1122H
MOV BX, 3344H
MOV SP, 3110H
PUSH AX
PUSH BX
MOV AX, 0
MOV BX, 0
POP BX
POP AX

5.1.4 PUSHF / POPF 16位标志寄存器进栈/出栈

格式:PUSHF ;	标志寄存器低16位压入堆栈
	POPF	; 从栈顶弹出2个字节送入标志寄存器低16位

5.1.5 XCHG交换 (exchange)

格式:XCHG OPR1, OPR2	;	(OPR1) <-> (OPR2)

类型:

5.1.6 CBW 字节转换为字 (convert byte to word)

c 复制代码
格式:CBW	;	AX <- AL符号扩展

5.1.7 CWD 字转换为双字 (convert word to byte)

c 复制代码
格式:CWD	; DX:AX <- AX符号扩展

低16位在AX,包括符号位的高16位在DX

5.1.7 LEA 有效地址送寄存器 (load effective address)

c 复制代码
格式:LEA REG, SRC	; (REG) <- (SRC)的有效地址

类型:

操作规则:

LEA经常用来初始化地址指针

示例如下:

体会一下LEA的作用

c 复制代码
MOV AX, MEM ; AX = 3412H
LEA AX, MEM ; AX = 3100H
MOV BX, 2000H
MOV DS, BX
MOV SI, 1000H
MOV AX, [BX+SI+102H] ; AX = 7856H
LEA BX, [BX+SI+102H] ; BX = 3102H

5.1.8 LAHF 标志送AH (load AH with flags)

c 复制代码
格式:LAHF	; AH <- flags低8位

5.1.9 AH 送 SAHF 标志寄存器 (store AH into flags)

c 复制代码
格式:SAHF	; flags低8位 <- AH

5.1.10 LDS、LES、LFS、LGS、LSS 指针送寄存器和段寄存器

c 复制代码
格式:LDS REG, SRC

功能:

(REG) <- [SRC]

(DS) <- [SRC + 2] (16位EA)

(DS) <- [SRC + 4] (32位EA)

例如:已知(DS)=5100H,(BX)=2000H

c 复制代码
LES DI, [BX]

5.1.11 XLAT 换码 (translate)

c 复制代码
格式:XLAT 

功能:完成代码转换,偏移量8位,表长 <= 256

16 位 指令 (AL) <- [(BX) + (AL)]

32 位 指令 (AL) <- [(EBX) + (AL)]

例如:我们通过下面的指令可以实现AL从09H -> 39H

已知(DS) = 5000H,(BX) = 4000H,(AL) <- 09H

c 复制代码
XLAT	; AL = 39H

5.1.12 IN / OUT 输入/输出 (不需要段地址)

(1)IN 输入指令(input)

1、直接寻址 (端口地址 <= 255)

c 复制代码
IN AL, n; 字节,(AL) <- (n)
IN AX, n; 字, (AL + 1) <- (n + 1) (AL) <- (n)
IN EAX, n; 双字, (EAX+3) <- (n+3),(EAX+2) <- (n+2),(EAX+1) <- (n + 1),(EAX) <- (n)

2、间接寻址(全部端口地址可用)

IN AL, DX; 字节, (AL) <- (DX)
IN AX, DX; 字, (AH) <- ((DX + 1)), (AL) <- (DX)
IN EAX, DX; 双字, 类似

(2)OUT 输出指令(output)

1、直接寻址 (端口地址 <= 255)

c 复制代码
OUT n, AL; 字节,(n) <- (AL)
OUT n, AX; 字
OUT n, EAX; 双字

2、间接寻址(全部端口地址可用)

OUT DX, AL; 字节, (DX) <- (AL)
OUT DX. AX; 字
OUT DX, EAX; 双字

5.2 算术运算指令

5.2.1 ADD加法

C 复制代码
格式:ADD DST, SRC; (DST) <- (SRC) + (DST)

类型:影响CF、PF、AF、ZF、SF、OF。可进行8、16、32位操作。

5.2.2 ADC 带进位加法指令 (add with carry)

c 复制代码
格式:ADC DST, SRC; (DST) <- (SRC) + (DST) + CF

和ADD唯一不同就是加了个CF

5.2.3 SUB减法 (subtract)

c 复制代码
格式:SUB DST, SRC; (DST) <- (DST) - (SRC)

5.2.4 SBB带借位减法 (subtract with borrow)

c 复制代码
格式:SBB DST, SRC; (DST) <- (DST) - (SRC) - CF

和ADD唯一不同就是减了个CF

5.2.5 INC 加1 (increment)

c 复制代码
格式:INC OPR ; (OPR) <- (OPR) + 1

5.2.6 DEC 减1 (decrement)

c 复制代码
格式:DEC  OPR ; (OPR) <- (OPR) - 1

5.2.7 NEG求补 (negate)

格式:NEG  OPR ; (OPR) <- ~(OPR) + 1,就是补码

3条指令共性说明:

  1. 目的操作数:通用寄存器、存储器单元,可以是8位、16位或32位
  2. 执行INC、DEC指令后,影响AF、OF、PF、SF、ZF,但对CF没有影响。
  3. 执行NEG指令后,影响AF、CF、OF、PF、SF、ZF这6个标志位。
  4. 如果原来的操作数为80H(即-128),执行NEG指令后,仍为80H,此时OF=1,溢出。
  5. 操作数=0时,在执行NEG指令后,CF=0;其他操作数,执行NEG指令后,CF总为1。

5.2.8 CMP 比较(Compare)

把大小关系转化为标志位的状态

c 复制代码
格式:CMP OPR1, OPR2; (OPR1) - (OPR2)

5.2.9 MUL 无符号乘法(unsigned multiple)

c 复制代码
格式:MUL SRC

功能:

  • 字节乘 (AX) ← (AL) × (SRC)
  • 字乘 (DX:AX) ← (AX) × (SRC)
  • 双字乘 (EDX:EAX) ← (EAX) × (SRC)

说明:

  1. 乘数和被乘数必须等长
  2. SRC:通用寄存器、存储器单元。
  3. 被乘数:默认AL、AX、EAX之一
  4. 若乘积的高半部分结果为0,则CF=0、OF = 0;否则,CF = 1、OF = 1。而AF、PF、ZF、SF无定义,即状态不定。

5.2.10 IMUL 带符号数乘法 (signed multiple)

c 复制代码
格式1:IMUL SRC

功能:

  • 字节乘 (AX) <- (AL) × (SRC)
  • 字乘 (DX:AX) <- (AX) × (SRC)
  • 双字乘 (EDX:EAX) <- (EAX) × (SRC)

5.2.11 DIV 无符号数除法 (unsigned divide)

c 复制代码
格式:DIV SRC

功能:

  • 字节除(AL) ← (AX)/(SRC)的商,(AH)←(AX)/(SRC)的余数,如果结构一个字节装不下就是除法溢出,下面类似不再赘述
  • 字除(AX) ← (DX:AX)/(SRC)的商,(X)←(X:AX)/(SRC)的余数
  • 双字除(EAX) ← (EDX:EAX)/(SRC)的商,(EDX)←(EDX:EAX)/(SRC)的余数

说明:

被除数默认在AX、DX:AX、EDX:EAX中。SRC是通用寄存器、存储器单元。所有标志位无定义。

5.2.12 IDIV 带符号数除法 (signed divide)

c 复制代码
格式:IDIV SRC

功能:和DIV指令相同

5.3 BCD码调整指令

在 Pentium 微处理器中,表示十进制数的 BCD 码可以用压缩的 BCD 码和非压缩的BCD码两种格式来表示。

压缩的BCD码,每4位二进制数表示一位十进制数,每字节存2个BCD 码,对于n位十进制数,则需用4 × n位二进制数。

非压缩的BCD码,每字节用低 4位表示1位 BCD 码,而高4位无意义。

而我们的运算指令只适用于二进制运算,所以我们需要针对BCD码的调整指令来将BCD码调整为二进制数。

5.3.1 DAA 压缩BCD码加法调整(decimal adjust for addition)

c 复制代码
格式: DAA

功能:

  1. 如果AL 的低4位大于9或AF=1,则(AL)+6→(AL)和 1→AF。
  2. 如果AL 的高4位大于9或CF=1,则(AL)+60H→(AL) 和 1→CF。

说明:

  1. 只对AL调整
  2. OF无定义, 其他5个状态受影响

例:

c 复制代码
MOV AL, 54H;	54H代表十进制数54
MOV BL, 37H;	37H代表十进制数37
ADD AL, BL;		AL中的和为十六进制数8BH
DAA	;		AL = 91H, AF = 1, CF = 0

5.3.2 DAS 压缩BCD码减法调整 (decimal adjust for subtraction)

c 复制代码
格式: DAS

功能:

  1. 如果AL的低4位大于9或AF=1,则(AL)-6→(AL)和 1→AF
  2. 如果AL的高4位大于9或CF=1,则(AL)-60H→(AL)和 1→CF

5.3.3 AAA 非压缩BCD码加法调整 (ASCII adjust for addition)

c 复制代码
格式: AAA

功能:

  1. 如果AL的低4位小于等于9,并且AF=0,则转步骤3;

  2. (AL)+6→AL, 1→AF, (AH)+1→AH;

  3. AL高4位清0;

  4. AF→CF。

说明: 影响AF和CF, 而PF、SF、ZF、OF无定义。

5.3.4 AAS 非压缩BCD码减法减整 (ASCII adjust for subtraction)

c 复制代码
格式: AAS

功能:

  1. 如果AL的低4位小于等于9,并且AF=0,则转步骤3;
  2. (AL) - 6 → AL,1 → AF,(AH) - 1 → AH;
  3. AL高4位清0;
  4. AF→CF。

5.3.5 AAM 非压缩BCD码乘法调整 (ASCII adjust for multiplication)

c 复制代码
格式: AAM

**格式:**AAM

功能:(AL)/0AH→(AH),余数→(AL)

**说明:**影响SF、ZF、PF,而OF、AF、CF无定义。

5.3.5 AAD 非压缩BCD码除法调整 (ASCII adjust for division)

c 复制代码
格式: AAD

功能:(AH) × 10 + (AL)→(AL),0 → (AH)

**说明:**先调整后运算。影响SF、ZF、PF,而OF、CF和AF无定义

5.4 逻辑运算指令

5.4.1 AND 按位逻辑与运算

c 复制代码
格式:AND DST,SRC;  (DST) <- (DST) & (SRC)

5.4.2 OR 按位逻辑或运算

c 复制代码
格式:OR DST,SRC;  (DST) <- (DST) | (SRC)

5.4.3 XOR 按位逻辑异或运算(exclusive or)

c 复制代码
格式:  XOR DST, SRC;  (DST) ← (DST) ^ (SRC)

5.4.4 TEST 按位逻辑比较运算

将两个操作数按位与,但是不影响操作数

c 复制代码
格式:TEST OPR1, OPR2;  (OPRI) & (OPR2)

4条指令类型:同ADD。

4条指令说明:CF、OF置0,影响SF、ZF、PF,AF无定义。

5.4.5 NOT按位取反

格式: N O T O P R ; ( O P R ) ← O P R ‾ 格式:NOT OPR ; (OPR) \leftarrow \overline{OPR} 格式:NOTOPR;(OPR)←OPR

**类型:**通用寄存器、存储器单元,8位、16位、32位。

**说明:**不影响标志位。

5.5 位处理指令

5.5.1 SHL 逻辑左移(shift logical left)

c 复制代码
格式:SHL OPR, CNT

5.5.2 SAL 算术左移(shift arithmetric left)

c 复制代码
格式:SAL OPR, CNT

5.5.3 SHR 逻辑右移(shift logical right)

c 复制代码
格式:SHR OPR, CNT

5.5.4 SAR 算数右移(shift arithmetric right)

c 复制代码
格式:SAR OPR, CNT

移位指令说明:

  1. OPR:通用寄存器、存储器单元。8位、16位、32位。
  2. CNT:8位立即数(1 - 31,8086中只能为1)、CL。
  3. CF依操作设置。OF当CNT=1时有效。

5.5.5 ROL 循环左移(rotate left)

c 复制代码
ROL OPR, CNT

5.5.6 ROR 循环右移(rotate right)

c 复制代码
 ROR OPR, CNT

5.5. 7 RCL 带进位循环左移(rotate left through carry)

RCL OPR, CNT

5.5.8 RCR 带进位循环右移(rotate right through carry)

c 复制代码
RCR OPR, CNT

5.6 控制转移指令

5.6.1 无条件段内相对短转移(jump)

c 复制代码
格式:JMP SHORT OPR

功能: (IP)←(IP) + 8位位移量 或 (EIP) ← (EIP) + 8位位移量

说明: SHORT是短转移属性描述符,8位位移量是一个带符号数,范围是-128到+127字节。

5.6.2 无条件段内相对近转移

c 复制代码
格式:JMP NEAR PTR OPR

功能: (IP) ← (IP) + 16位位移量 或 (EIP) ← (EIP) + 32位位移量

说明: NEAR是近转移属性描述符,16位、32位位移量是一个带符号数。即和对应字长一样大小。

5.6.3 无条件段内间接转移

c 复制代码
JMP OPR; OPR可以是寄存器、存储器

功能: (IP)←(EA) 或 (EIP)←(EA)

5.6.4 无条件段间直接转移

C 复制代码
格式: JMP FAR PTR OPR ; OPR为指令的标号(即指令地址)

功能:

  • (IP/EIP)←OPR的段内偏移地址
  • (CS)←OPR所在段的段地址

5.6.5 无条件段间间接转移

格式:  JMP DWORD PTR OPR; OPR为存储器单元

功能:

  • (IP/EIP)←[EA]
  • (CS)←[EA+2] / EA+4]

5.6.6 条件相对转移(8位偏移量)

1、单条件相对转移

c 复制代码
JZ/JE OPR; ZF=1转移(结果为零或相等转移)
JNZ/JNE OPR; ZF=0转移(结果不为零或不相等转移)
JS OPR; SF=1; 转移(结果为负转移)
JNS OPR SF=0; 转移(结果为正转移)
JO OPR; OF=1转移(结果溢出转移)
JNO OPR; OF=0转移(结果不溢出转移)
JP/JPE OPR;PF=1转移(结果为偶转移)
INP/JPO OPR; PF=0 转移(结果为奇转移)
JC OPR; CF=1转移(有借位或有进位转移)
JNC OPR; CF=0 转移(无借位或无进位转移)
  • J:jump E:equal Z:zero N:not
  • S:sign P:parity C:carry O:over flow
  • PE:parity even PO:parity odd

2、无符号数比较条件相对转移(A-B,Above,Below)

  • JB / JNAE / JC OPR ; CF=1 (A<B转移)

  • JAE / JNB / JNC OPR ; CF=0 (A>=B转移)

  • JBE / JNA OPR ; (CF V ZF)=1 (A <= B转移)

  • JA / INBE OPR ; (CF V ZF)=0 (A > B转移)

3、有符号数比较条件相对转移 (G-L,Greater,Less)

  • JL / JNGE OPR ; (SF xor OF)=1 (A<B转移)

  • JGE / JNL OPR ; (SF xor OF)=0 (A>=B转移)

  • JLE / JNG OPR ; ((SF xor OF) V ZF)=1(A≤B转移)

  • JG / INLE OPR ; ((SF xor OF) V ZF)=0(A>B转移)

4、测试CX条件相对转移

  • JCXZ OPR ;(CX)=0转移

5.6.7 LOOP循环控制相对转移

**格式:**LOOP OPR

功能:(CX/ECX) <- (CX/ECX) - 1; (CX/ECX) != 0 转移

5.6.8 LOOPZ/LOOPE循环控制相对转移

**格式:**LOOPZ/LOOPE OPR

功能:(CX/ECX) <- (CX/ECX) - 1; (CX/ECX) != 0 且 ZF = 1转移

5.6.9 LOOPNZ/LOOPNE循环控制相对转移

**格式:**LOOPNZ(或LOOPNE) OPR

功能:(CX/ECX)<- (CX/ECX) - 1; (CX/ECX) != 0 且 ZF = 0 转移

**说明:**上述三条循环控制相对转移指令中的转移地址为(IP/EIP )<- (IP/EIP) + 8位带符号数;8位位移量是由目标地址OPR确定的。

5.6.10 子程序调用与返回

**子程序:**具有独立功能的程序模块。

程序中可由调用程序(或称主程序)调用这些子程序,而在子程序执行完后又返回调用程序继续执行。为实现这一功能,微机提供了CALL调用指令和RET返回指令。

  1. 段内相对调用

    1. 格式:CALL DST; DST为直接入口地址,指令中给出

      ​ CALL NEAR PTR DST

    2. 功能:

      操作数16位:

      ​ SP <- (SP) - 2, [SP] <- (IP)

      ​ IP <- (IP) + 16位位移量

      操作数32位:

      ​ ESP <- (ESP) - 4, [ESP] <- (EIP)

      ​ EIP <- (EIP) + 32位位移量

    3. 说明:16、32位位移量是一个有符号数

  2. 段内间接调用

    1. 格式:CALL DST ; DST为R、M

    2. 功能:

      操作数16位:

      ​ SP <- (SP) - 2, [SP] <- (IP)

      ​ (IP) <- (EA)

      操作数32位:

      ​ ESP <- (ESP) - 4, [ESP] <- (EIP)

      ​ (EIP) <- (EA)

    3. **类型:**寄存器、存储器单元

  3. 段间直接调用

    1. 格式:CALL DST ; DST为直接入口地址,指令中给出

    2. 功能:

      操作数16位:

      ​ SP <- (SP) - 2, [SP] <- (CS)

      ​ SP <- (SP) - 2, [SP] <- (IP)

      ​ IP <- DST的偏移地址

      ​ CS <- DST所在段的段地址

      操作数32位:

      ​ ESP <- (ESP) - 2, [ESP] <- (CS)

      ​ ESP <- (ESP) - 4, [ESP] <- (EIP)

      ​ ESP <- DST的偏移地址

      ​ CS <- DST所在段的段地址

    3. 说明:该指令先将CS、IP或EIP压栈保护返回地址。然后转移到由DST(DST为汇编语言中的过程名)指定的转移地址。

  4. 段间间接调用

    1. 格式:CALL DST;DST为M

    2. 功能:

      操作数16位:

      ​ SP <- (SP) - 2, [SP] <- (CS)

      ​ SP <- (SP) - 2, [SP] <- (IP)

      ​ IP <- (EA)

      ​ CS <- (EA + 2)

      操作数32位:

      ​ ESP <- (ESP) - 2, [ESP] <- (CS)

      ​ ESP <- (ESP) - 4, [ESP] <- (EIP)

      ​ EIP <- (EA)

      ​ CS <- (EA + 4)

    3. 说明:先保护返回地址,然后转移到由DST指定的转移地址。EA由DST确定的任何内存寻址方式

  5. 段内返回

    1. **格式:**RET

    2. 功能:

      操作数16位:IP <- 栈弹出2字节, SP <- (SP) + 2

      操作数32位:(EIP) <- 栈弹出4字节,ESP <- (ESP) + 4

  6. 段内带参数返回

    1. **格式:**RET
    2. 功能:
      操作数16位:IP <- 栈弹出2字节,SP<- (SP) + 2
      SP <- (SP) + N
      操作数32位:EIP <- 栈弹出4字节,ESP <- (ESP) + 4
      ESP <- (ESP)+N
    3. **说明:**N是一个16位的常数(偶数)
  7. 段间返回

    1. **格式:**RET
    2. 功能:
      **操作数16位:**IP <- 栈弹出2字节,SP <- (SP)+2
      CS <- 栈弹出2字节,SP <- (SP)+2
      操作数32位:
      EIP <- 栈弹出4字节,ESP <- (ESP)+4
      CS <- 栈弹出2字节,ESP <- (ESP)+2
  8. 段间带参数返回

    1. **格式:**RET N

    2. 功能:

      操作数16位:

      IP <- 栈弹出2字节,SP <- (SP)+2

      CS <- 栈弹出2字节,SP <- (SP)+2

      SP <- (SP)+N

      操作数32位:

      EIP <- 栈弹出4字节,ESP <- (ESP)+4

      CS <- 栈弹出2字节,ESP <- (ESP)+2

      ESP <- (ESP)+N

5.6.11 中断指令

**中断指令作用:**调用中断服务程序。中断向量地址 = 中断类型码 × 4。

(1)INT 中断指令

**格式:**INT n ; 不影响标志位
功能:

  1. SP <- (SP) - 2
  2. PUSH (FR);标志寄存器FR进栈
  3. SP <- (SP) - 2
  4. PUSH(CS);断点段地址CS进栈
  5. SP <- (SP) - 2
  6. PUSH (IP);断点地址指针IP进栈
  7. TF <- 0;禁止单步
  8. IF <- 0;禁止中断
  9. IP <- [n × 4];转向中断服务程序
  10. CS <- [n × 4 + 2];

(2)INT3 中断断点

**格式:**INT3;同 INT n

**说明:**产生类型为3的中断,不影响标志位。

(3)INTO 溢出中断

**格式:**INTO;OF=1产生类型为4的中断,OF = 0顺序执行下条指令。

**说明:**产生中断时,TF <- 0,IF <- 0,其他标志位不受影响。

(4)IRET中断返回

**格式:**IRET;标志位随标志寄存器出栈操作而不变

功能:

  1. IP <- 栈弹出2字节;断点偏移量出栈
  2. SP <- (SP)+2
  3. CS <- 栈弹出2字节;断点段地址出栈
  4. SP <- (SP)+2
  5. FR <- 栈弹出2字节;标志寄存器出栈
  6. SP <- (SP) + 2

(5)INT 21H 系统功能调用

**系统功能调用:**DOS为系统程序员及用户提供的一组中断服务程序。

DOS规定用中断指令INT 21H作为进入各功能调用中断服务程序的总入口,再为每个功能调用规定一个功能号,以便进入相应各个中断服务程序的入口。

程序员使用系统功能调用的过程:

  1. AH <- 功能调用编号
  2. 设置入口参数
  3. CPU执行 INT 21H
  4. 给出出口参数

DOS共提供了约80个功能调用

  1. 功能号:1;等待键盘输入,并回送显示器

    MOV AH,1;(AH)一功能号01H

    INT 21H;调用21H号软中断

    **说明:**出口参数(AL) = 键入字符的ASCII码。

  2. **功能号:2;**输出字符送显示器

    MOV DL,41H;入口参数:(DL) <- 字符 A 的ASCII码

    MOV AH,2;(AH) <- 功能号02H

    INT 21H;在屏幕上显示输出字符A

    **说明:**无出口参数。

  3. 功能号:4CH;终止程序,返回

    MOV AH,4CH;(AH) <- 功能号4CH

    INT 21H;调用21H号软中断

5.7 串操作指令

串操作指令处理连续存放在存储器中的数据。(相比于多次单个处理,效率更高)

X86系列CPU有7个串操作指令,其中与存储器相关的5个,与I/O相关的2个。

**存储器相关的5个:**传送MOVS、比较CMPS、扫描SCAS、装入LODS、存储STOS

**与IO相关的2个:**输入INS、输出OUTS

共同特性:

  1. **数据类型:**字节、字、双字

  2. **源串:**DS:SI/ESI,允许段超越

  3. **目的串:**ES:DI/EDI

  4. 每执行一次串操作指令,SI/ESI、DI/EDI自动修改,指向下一位置。

  5. **地址修改方向:**由DF控制,DF=0增址(CLD),DF=1减址(STD)

  6. 带B、W、D为隐式,否则为显式,如MOVS BYTE PTR[DI],[SI]

  7. 指令中只给出一个操作数时,另一个隐含为AL、AX、EAX之一。

  8. 可加相应的重复前缀,赋值CX/ECX为计数值。

1、MOVS 串传送(move string)

  • 格式: MOVS DST, SRC

    MOVSB(字节)

    MOVSW(字)

    MOVSD(双字)(自386起有)

  • 功能: ES:[DI/EDI] <- DS:[SI/ESI] ; 不影响标志位

    ​ 字节传送: (DI/EDI) <- (DI/EDI) ± 1

    ​ (SI/ESI) <- (SI/ESI) ± 1

    ​ 字传送: (DI/EDI) <- (DI/EDI) ± 2

    ​ (SI/ESI) <- (SI/ESI) ± 2

    ​ 双字传送: (DI/EDI) <- (DI/EDI) ± 4

    ​ (SI/ESI) <- (SI/ESI) ± 4

2、LODS串装入(load from string)

  • 格式: LODS SRC; 字节装入 AL <- DS:[SI/ESI]

3、STOS串存储(store into string)

  • 格式: STOS DST; 字节存储 ES:[DI/EDI] <- AL

4、CMPS串比较(compare string)

  • 格式: CMPS DST, SRC;DS:[SI/ESI] - ES:[DI/EDI], 影响标志位

5、SCAS 串扫描(scan string)

  • 格式: SCAS DST ; 字节扫描(AL)- ES:[DI/EDI], 影响标志位

6、INS串输入(input from port to string)

  • 格式: INS DST, DX; ES:[DI/EDI] <- [DX]

7、OUTS串输出(output string to port)

  • 格式: OUTS DX, SRC; [DX] <- DS:[SI/ESI]

8、REP 计数重复串操作(repeat)

  • 格式: REP OPR ; OPR是MOVS、STOS、LODS、INS、OUTS
  • 功能:
    1. 如果(CX) = 0,则退出REP,否则往下执行
    2. (CX) <- (CX) - 1
    3. 执行其后的串指令
    4. 重复①~③

9、REPZ 计数相等重复串操作(repeat while zero/equal)

  • 格式: REPZ/REPE OPR ; OPR是CMPS、SCAS
  • 功能:
    1. 如果(CX) = 0或ZF = 0,则退出REP,否则往下执行
    2. (CX) <- (CX) - 1
    3. 执行其后的串指令
    4. 重复①~③

10、REPNZ 计数不相等重复串操作(repeat while not zero/ not equal)

  • 格式: REPNZ/REPNE OPR ; OPR是CMPS、SCAS
  • 功能:
    1. 循环条件和REPZ相反

5.8 处理器控制指令

5.8.1 标志处理指令

标志处理指令只设置或清除本指令的标志位而不影响其他标志位。

  • CLC;进位位置0,CF <- 0(clear carry)
  • CMC;进位位取反, C F ← C F ‾ CF \leftarrow \overline{CF} CF←CF (complement carry)
  • STC;进位位置1,CF <- 1 (set carry)
  • CLD;方向标志位置0,DF <- 0 (clear direction )
  • STD;方向标志位置1,DF <- 1 (set direction )
  • CLI;中断标志置0,IF <- 0,禁止中断 (clear interrupt)
  • STI ;中断标志置1,IF <- 1,允许中断(set interrupt)

5.8.2 处理器控制指令

处理器控制指令可以控制处理机状态。它们都不影响条件码。

**1)HLT;**暂停

暂停指令停止软件的执行。有三种方式退出暂停:中断、硬件复位、DMA操作。

2)NOP;空操作

不执行任何操作。

3)ESC;换码

指定由协处理器执行的指令。486后浮点处理部件已装入CPU,系统可直接支持协处理器指令,因此ESC指令已成为未定义指令。

4)WAIT;等待

使处理机处于空转状态,它也可以用来等待外部中断发生,但中断结束后仍返回WAIT指令继续等待。

5)LOCK ;封锁前缀

有此前缀的指令执行后,CPU封锁总线,禁止其他总线主设备访问总线。如 LOCK MOV AL, [SI]

5.9 伪指令

**伪指令功能:**指示汇编程序完成规定的操作。如选择处理器、定义数据、分配存储区等。

5.9.1 程序开始和结束伪指令

END 源程序结束伪指令

  • **格式:**END [标号]
  • **功能:**表示源程序结束,不可缺,源程序最后一条语句
  • 说明:
    1. 标号指示程序开始执行的起始地址。
    2. 主程序缺省值为代码段的第一条指令的地址。
    3. 多个模块链接,主程序用标号,其他程序不用

5.9.2 段定义伪操作

**段定义:**确定代码组织与数据存储的方式,

**有2种段定义伪指令:**完整的段定义、简化的段定义。

简化的段定义伪指令只能在MASM 5.0以上的汇编语言版本中使用。

1.完整的段定义伪操作

(1)SEGMENT、ENDS 段定义伪指令

**格式:**段名 SEGMENT[定位类型][组合类型][字长类型]['类别']

段名 ENDS

**功能:**定义段名、段属性,并表示段的开始位置、结束位置。

说明:

  1. SEGMENT和ENDS必须成对出现,而且伪指令前面的段名也要相同
  2. 段名是段的标识符,指明段的基址,由程序员指定。
  3. 一般情况下,选项可以不用,使用默认值。但若需链接程序,就必须使用这些说明

**1、定位类型:**指定段起始地址边界。

5种定位类型:

  1. **BYTE:**任意地址。
  2. **WORD:**偶地址,地址最低1位为0。
  3. **DWORD:**4的倍数地址,地址最低2位为0。
  4. **PARA:**16的倍数地址,地址最低4位为0。默认值
  5. **PAGE:**256的倍数地址,地址最低8位为0。一页的起点。

**2、组合类型:**表示本段与其他模块段之间,具有相同段名的各段的组合关系。

注意3个前提:连接时,类型相同,段名相同

6种组合类型:

  1. PUBLIC :连接时,把不同模块中类型相同、段名相同的段连接到同一物理存储段中,共用一个段地址。连接次序由连接命令指定。即同名段连接在一起,有共同段地址。
  2. STACK :用于说明堆栈段。与PUBLIC的处理方式一样,长度为各原有段的总和。LINK自动将新段的段地址送SS,
    长度送SP/ESP。若未定义STACK类型,需在程序中用指令设置SS、SP。
  3. COMMON :连接时,使类型相同、段名相同的段具有同一个起始地址,即生一个覆盖段。新段的长度是最长COMMON段的长度,新段的内容取决于依次覆盖的最后内容。
  4. MEMORY:表示该段定位在所有段的最下面(即地址最大的区域),多个MEMORY段产生覆盖,连接时与PUBLIC类型同等对待。
  5. PRIVATE:独立段,不与同名段合并。默认值。
  6. AT 表达式:指定本段起始地址为"表达式",偏移量为0,不能用于代码段。

**3、字长类型:**386以后,说明使用16位寻址还是32位寻址。

2种字长类型:

**1)USE16:**16位寻址,段长 ≤ 64KB,16位段地址,16位偏移量。默认值

**2)USE32:**32位寻址,段长 ≤ 4GB,16位段地址,32位偏移量。

4、类别:引号括起来的字符串。连接时,类别相同的段(它们可能不同名)放在连续的存储空间中,但它们仍然是不同的段。

4种类别:

  1. **DATA:**段类别是数据段。
  2. **CODE:**段类别是代码段。
  3. **STACK:**段类别是堆栈段。
  4. **EXTRA:**段米别是附加数据段

(2)ASSUME 段分配伪指令

格式:

ASSUME 段寄存器名:段名,段寄存器名:段名,...

**功能:**说明某个段使用哪一个段寄存器。

说明:

  1. 程序段必须用CS,堆栈段必须用SS。
  2. 该语句一般放在代码段最前面。
  3. 说明性语句,除CS外(初始化赋值),各段寄存器在程序中赋值。
  4. 取消语句:ASSUME NOTHING

5.9.2 地址计数器伪指令

1、地址计数器$

功能:指出汇编地址,是偏移量,记载下一个变量或指令在当前段中的偏移量。

每个段开始时,=0,随着汇编过程的进行而增值。每处理一条指令,增加一个值,此值是该指令所需的字节数。

允许直接引用$,如JNE $ + 6,转向JNE指令的首地址加上6。

$用于指令时,表示本条指令的第一个字节的地址;

用于其他情况,表示的当前值.

2、ORG 地址计数器设置(起始地址定义)

**格式:**ORG 数值表达式

**功能:**定义指令或数据的起始地址,$ ← 表达式的值。

**说明:**数值表达式取值范围在 0 ~ 65535 之间。

3、EVEN 偶数地址定义(使地址计数器成为偶数)

**格式:**EVEN

**功能:**使下一个变量或指令从偶地址开始。

**说明:**便于字存储对准。EVEN在代码段中可能多出一个NOP语句。

4、ALIGN 边界定义(使地址计数器满足边界要求)

**格式:**ALIGN n;n必须是2的整数幂, n = 2 i n = 2^i n=2i

**功能:**使下一个变量或指令从n的整倍数地址开始,

**说明:**保证双字、四倍字对准。当 n = 2 时,即 ALIGN 2 和 EVEN 是等价的。

5.9.3 数据定义伪指令

格式:

[变量名] 操作符 操作数 [;注释]

**功能:**为操作数分配存储单元,用变量与存储单元相联系。

变量名和注释是可有可无的。

**操作符:**定义操作数类型。

**DB:**一个操作数占有1个字节单元(8位),定义的变量为字节变量。

**DW:**一个操作数占有1个字单元(16位),定义的变量为字变量。

**DD:**一个操作数占有1个双字单元(32位),定义的变量为双字变量

DF:一个操作数占有1个三字单元(48位),定义的变量为三字变量

DQ:一个操作数占有1个四字单元(64位),定义的变量为四字变量

DT:一个操作数占有1个五字单元(80位),定义的变量为五字变量

**操作数:**常数、表达式、字符串、?等。

特别说明1:字符串

操作数是字符串定义形式

包括在单引号中的若干个字符形成字符串,字符串在存储中存储的是相应字符的ASCII码。

当定义的字符串中字符多于2个时,只能使用DB定义,而不能使用DW。汇编程序将DW 'AB' 按一个字来处理。

特别说明2:"?"

操作数是 "?" 定义形式.

此时只分配存储空间,但不定义初值。

ASN.1 复制代码
DATA1 DB 1, 2, ?, 4

特别说明3:DUP

操作数用复制操作符DUP定义形式,此时表示操作数重复若干次。

ASN.1 复制代码
DATA1 DB 2 DUP(12H, 34H, 56H)

含义是把括号内的数据复制两次

5.9.4 PROC和ENDP过程定义伪指令

格式:

过程名 PROC(属性]

(过程体)

过程名 ENDP

**功能:**用于定义子程序结构,定义一段程序的入口(过程名)及属性。

**说明:**过程名是该过程(子程序)的入口,是CALL的操作数。

**属性:**FAR、NEAR(默认)

5.10 操作数字段

操作数包括:寄存器、变量、标号、常数、表达式

5.10.1 常数

**常数:**主要用作指令中的直接操作数,也可作为存储变量操作数的组成部分,或者在伪指令中用于给变量赋初值。

**常数包括:**数值常数、符号常数、字符串常数

1.数值常数

**数值常数:**2进制数B、8进制数Q、10进制数D(默认)、16进制数H

格式:.RADIX数值表达式;基数控制伪指令

**功能:**把默认的基数改变为2~16范围内的任何基数。

2.字符串常数

**字符串常数:**在单引号中的若干个字符。

字符串在存储中存储的是相应字符的ASCII码。

3、符号常数

(1) EQU赋值伪指令

**格式:**符号常数名 EQU 表达式;将表达式的值赋给符号常数

**说明:**表达式可以是有效的操作数格式,也可以是任何可求出数值常数的表达式,还可以是任何有效的符号(如操作符、存器、委量

注意:只能定义一次。

ASN.1 复制代码
DATA1	EQU 88	;所有出现DATA1的地方都会替换为88
AAAI	EQU CX	;同理
DATA2	EQU DATA1 + 12	;同理

(2) = 伪指令

**格式:**符号常数名 = 表达式;同EQU伪指令

注意:可重复定义(和EQU的区别)

ASN.1 复制代码
DATA1 = 88;
DATA1 = DATA1+99;

5.10.2 表达式

表达式是一个组合序列,包括常数、寄存器、标号、变量。

**两种形式:**数字表达式、地址表达式。

1.运算符

**6种:**算术运算、逻辑运算、移位运算、关系运算、返回值运算、属性运算。

  1. **算术运算符:**+、-、*、/、MOD
  2. **逻辑运算符:**AND、OR、XOR、NOT
  3. **移位运算符:**左移SHL、右移SHR
  4. **关系运算符:**等于EQ、不等NE、小于LT、大于GT、小于等于LE、大于等于GE。
    • 关系运算符的两个操作数的**计算结果应为逻辑值:**结果为真(即关系成立),表示为0FFFFH,结果为假(即关系不成立),则表示为0。

5.返回值运算符

**返回值运算符:**返回变量或标号的段地址(SEG)、返回变量或标号的偏移地址(OFFSET)、返回变量或标号的类型值(TYPE)、返回变

量的单元数(LENGTH)、返回变量的字节数(SIZE):

  • 操作数 SEG 变量/标号;段地址值赋给操作数。
  • 操作数 OFFSET 变量/标号;偏移量值赋给操作数。
  • 操作数 TYPE 变量/标号;代表变量/标号类型的值赋给操作数。
  • 操作数 LENGTH 变量;第一个数占用的单元数赋给操作数。
  • 操作数 SIZE 变量;第一个数占用的字节数赋给操作数。

**TYPE:**变量DB返回1、DW返回2...标号NEAR返回-1、FAR返回-2.

LENGTH:只对DUP定义的变量有意义,返回分配给该变量的元素的个数(不是字节数),其他情况均送1。

SIZE:只对DUP定义的变量有意义,返回分配给该变量的字节数。SIZE = LENGTH × TYPE

6.属性运算符

1)PTR 属性说明运算符

**格式:**类型 PTR 变量/标号;临时改变类型属性

**说明:**变量:字节BYTE、字WORD、双字DWORD、三字FWORD、四字QWORD、五字TWORD;

标号:近类型NEAR、远类型FAR。

2)THIS 指定类型属性运算符

**格式:**变量/标号 EQU THIS 类型

**功能:**将变量或标号定义成指定的类型。

**说明:**THIS指定的变量或标号本身并不分配存储单元,它与紧跟其后的变量或标号只有类型不同,而段地址和偏移量均相同,从而便于程序设计。该指令可以指定的类型与PTR相同。

5.10.3 数字表达式

**数字表达式:**由常数、变量、标号与一些运算符相组合的序列。它的结果必须是常数。

ASN.1 复制代码
MOV DX, (AAA1 LT 3 AND 10H OR AAA1 GE 3 AND 0AFH) SHL 2

5.10.4 变量

**变量:**数据单元的符号地址,

**5种属性:**段值、偏移值、类型、单元数(也称长度)、字节数。

  • **段值属性:**变量所在段的段地址。
  • **偏移值属性:**变量的偏移地址。
  • **类型属性:**变量一个数据的字节数。
  • **长度属性:**变量在数据区中的单元数。
  • **字节数属性:**在数据区中分配给该变量的字节数。

在同一个程序中,相同的变量或标号名只允许定义一次,否则,汇编时汇编程序指出错误。

5.10.5 地址表达式

**地址表达式:**其值是存储器地址,即EA的计算。

地址表达式使用规则:

  1. 变量和标号可以加上或减去某个结果为整数的数值表达式。

  2. 同一段内的变量和变量、标号和标号之间可以相减。

  3. 寄存器的内容可作为地址使用,用"[]"表示。方括号"[]"内可以出现一个或两个寄存器,也可加、减某个数值表达式,但不能有变量或标号出现。

  4. 可以使用段超越前缀,其格式为:

    段寄存器/段名:变量/标号/地址表达式

  5. 地址表达式的书写格式:

    ASN.1 复制代码
    MOV AX, [BX + SI + 8]
    MVO AX, [BX + SI]8
    MOV AX, [BX][SI]8
    MOV AX, 8[BX + SI]

符:**AND、OR、XOR、NOT

  1. **移位运算符:**左移SHL、右移SHR

  2. **关系运算符:**等于EQ、不等NE、小于LT、大于GT、小于等于LE、大于等于GE。

  • 关系运算符的两个操作数的**计算结果应为逻辑值:**结果为真(即关系成立),表示为0FFFFH,结果为假(即关系不成立),则表示为0。

5.返回值运算符

**返回值运算符:**返回变量或标号的段地址(SEG)、返回变量或标号的偏移地址(OFFSET)、返回变量或标号的类型值(TYPE)、返回变

量的单元数(LENGTH)、返回变量的字节数(SIZE):

  • 操作数 SEG 变量/标号;段地址值赋给操作数。
  • 操作数 OFFSET 变量/标号;偏移量值赋给操作数。
  • 操作数 TYPE 变量/标号;代表变量/标号类型的值赋给操作数。
  • 操作数 LENGTH 变量;第一个数占用的单元数赋给操作数。
  • 操作数 SIZE 变量;第一个数占用的字节数赋给操作数。

**TYPE:**变量DB返回1、DW返回2...标号NEAR返回-1、FAR返回-2.

LENGTH:只对DUP定义的变量有意义,返回分配给该变量的元素的个数(不是字节数),其他情况均送1。

SIZE:只对DUP定义的变量有意义,返回分配给该变量的字节数。SIZE = LENGTH × TYPE

6.属性运算符

1)PTR 属性说明运算符

**格式:**类型 PTR 变量/标号;临时改变类型属性

**说明:**变量:字节BYTE、字WORD、双字DWORD、三字FWORD、四字QWORD、五字TWORD;

标号:近类型NEAR、远类型FAR。

2)THIS 指定类型属性运算符

**格式:**变量/标号 EQU THIS 类型

**功能:**将变量或标号定义成指定的类型。

**说明:**THIS指定的变量或标号本身并不分配存储单元,它与紧跟其后的变量或标号只有类型不同,而段地址和偏移量均相同,从而便于程序设计。该指令可以指定的类型与PTR相同。

5.10.3 数字表达式

**数字表达式:**由常数、变量、标号与一些运算符相组合的序列。它的结果必须是常数。

ASN.1 复制代码
MOV DX, (AAA1 LT 3 AND 10H OR AAA1 GE 3 AND 0AFH) SHL 2

5.10.4 变量

**变量:**数据单元的符号地址,

**5种属性:**段值、偏移值、类型、单元数(也称长度)、字节数。

  • **段值属性:**变量所在段的段地址。
  • **偏移值属性:**变量的偏移地址。
  • **类型属性:**变量一个数据的字节数。
  • **长度属性:**变量在数据区中的单元数。
  • **字节数属性:**在数据区中分配给该变量的字节数。

在同一个程序中,相同的变量或标号名只允许定义一次,否则,汇编时汇编程序指出错误。

5.10.5 地址表达式

**地址表达式:**其值是存储器地址,即EA的计算。

地址表达式使用规则:

  1. 变量和标号可以加上或减去某个结果为整数的数值表达式。

  2. 同一段内的变量和变量、标号和标号之间可以相减。

  3. 寄存器的内容可作为地址使用,用"[]"表示。方括号"[]"内可以出现一个或两个寄存器,也可加、减某个数值表达式,但不能有变量或标号出现。

  4. 可以使用段超越前缀,其格式为:

    段寄存器/段名:变量/标号/地址表达式

  5. 地址表达式的书写格式:

    ASN.1 复制代码
    MOV AX, [BX + SI + 8]
    MVO AX, [BX + SI]8
    MOV AX, [BX][SI]8
    MOV AX, 8[BX + SI]
相关推荐
小_太_阳2 分钟前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it3 分钟前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
古希腊掌管学习的神39 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师40 分钟前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
就爱学编程1 小时前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
每天都要学信号1 小时前
Python(第一天)
开发语言·python
TENET信条1 小时前
day53 第十一章:图论part04
开发语言·c#·图论
委员1 小时前
基于NodeMCU的物联网电灯控制系统设计
单片机·物联网·嵌入式·nodemcu··lu_asr01·gy-302