指令系统(四)

目录

汇编语言指令(一)

数据传送指令(7种)

image-20230218162308856

SAHF,POPF外,其余传送指令CPU执行后,对6个状态标志位(PSW)无影响

语法规则

  1. 立即数只能做源操作数
  2. 类型要一致
  3. 类型要明确
  4. DS、ES、SS作为目的时,源操作数不能是立即数
  5. IP不能做目的
  6. 两存储器单元之间不能直接操作
  7. 不允许两个变量直接参加运算

通用数据传送指令 MOV

格式:MOV DST, SRC

取有效地址指令 LEA

格式:LEA REG16, MEM

REG16:16位寄存器

MEM:5种寻址方式之一指明的存储单元

注意REG16最好使用 BX、BP、SI、DI

例:取DAT1的有效地址,放入BX

MOV BX, OFFSET DAT1
;等价于
LEA BX, DAT1

取地址指针指令 LDS/LES

格式:LDS/LES REG16, MEM

指令说明:MEM所指向的是一个32位(双字)存储空间,运行完指令后,将MEM所指向的存储空间的高16位存入 DS/ES中作为段地址,将MEM所指向的存储空间的低16位存入 REG16中作为偏移地址

例:某数x(字)所在存储单元的地址指针在 POINT双字单元中,将x取出放入 DX

;法一
LDS BX, POINT
MOV DX, [BX]
;法二
LES BX, POINT
MOV DX, ES:[BX]

标志传送指令 LAHF/SAHF

源和目的操作数均为隐含寻址

格式:

  • LAHF ;(AH)<--PSW低8位
  • SAHF ;(AH)-->PSW低8位

数据交换指令 XCHG

格式:XCHF DST, SRC

说明:

  1. DST、SRC均不能用立即数
  2. 段寄存器不能参加交换

例:

XCHG AX, BX		;(AX)<-->(BX)交换
XCHG AL, [SI+3]	;寄存器相对寻址
XCHG DH, DL		;DX高低8位互换
XCHG AX, ES		;语法错误,段寄存器不能参加交换
XCHG AX, BL		;语法错误,类型不一致

字节转换指令 XLAT

  1. 源和目的操作数均为隐含寻址
  2. 又名 查表指令

格式:XLAT ;AL<--(DS:(BX)+(AL))

例:有表:TAB DB 30H, 31H, 32H, 33H,... ,39H,取出字符 ‘4’

MOV AL, 4		;偏移地址存入AL,第4个字符
LEA BX, TAB		;取出TAB的地址
XLAT			;(AL)<--34H

堆栈操作指令 PUSH/POP/PUSHF/POPF

格式:

  • PUSH SRC:压栈,SRC不能是立即数
  • POP DST:出栈
  • PUSHF:将PSW压栈
  • POPF:将栈内一个字赋给PSW

说明:都必须按字操作

算术运算类指令(6种)

image-20230218195933137

注意

  1. CPU只要涉及运算,其结果就会影响6个状态标志
  2. 段寄存器不能参加运算(算术、逻辑)

加法指令 (3条)

  1. 不带进位位加法:ADD DST, SRC ;DST<--(SRC)+(DST),根据结果设置6个状态标志
  2. 带进位位加法:ADC DST, SRC ;DST<--)(SRC)+(DST)+CF,根据结果设置6个状态标志
  3. 增一指令:INC DST ;DST<--(DST)+1 ,设置除 CF以外的状态标志,对 CF没影响

例:设在DVAR开始的连续8字节中分别存放着两个数A和B(每个数32位),求C=A+B,并将结果C放到DVARC开始的内存中

解:设 A=00127654HB=00049821H,则在数据段中有变量定义语句:

DVAR DD 00127654H	;A
     DD 00049821H	;B
DVAR DD ?			;存放结果C

代码段

LEA SI, DVAR			;取DVAR的偏移地址
MOV AX, [SI]			;取A的低字到(AX)
ADD AX, [SI+4]			;AX与B的低字相加
MOV WORD PTR DAVRC, AX	;将结果存到C的低字
MOV AX, 2[SI]			;取A的高字到(AX)
ADC AX, [SI]+6			;注意考虑进位,用ADC,AX与B的高字相加
MOV WORD PTR DAVRC+2, AX;将结果存入C的高字

减法指令(5条)

  1. 不带借位位减法:SUB DST, SRC ;DST<--(DST)-(SRC),根据结果设置6个状态标志

  2. 带借位位减法:SBB DST, SRC ;DST<--(DST)-(SRC)-CF,根据结果设置6个状态标志

  3. 减一指令:DEC DST ;DST<--(DST)-1,设置除 CF以外的状态标志,对 CF没影响

    例:若 (AL)=0FFHCF=0,则CPU执行:INC AL指令后,(AL)=?CF=?

    由于 AL只能放8位,所以(AL)=0

    INCDEC不影响 CF,所以CF=0

  4. 比较指令:CMP DST, SRC ;(DST)-(SRC),根据差设置6个状态标志

    当程序做减法或比较时,会产生以下5个条件(CF、SF、ZF、PF、OF),AF不是条件

条件转移指令(插入节,18条)

​ 一般在比较指令后,会紧跟条件转移指令,根据产生的条件决定程序的转向。假设执行完指令:

MOV AL, a
CMP AL, b	;即a-b

​ 根据单个条件,每个条件对应两条指令,共10条:

  1. 根据 CF
    • JC 标号:结果产生进/借位,则转移
    • JNC 标号:结果没有产生进/借位,则转移
  2. 根据 SF
    • JS 标号:结果为正,则转移
    • JNS 标号:结果为负,则转移
  3. 根据 ZF
    • JZ/JE 标号:结果为0(相等),则转移
    • JNZ/JNE 标号:结果不为0(不相等),则转移
  4. 根据 PF
    • JP 标号:结果有偶数个1,则转移
    • JNP 标号:结果有奇数个1,则转移
  5. 根据 OF
    • JO 标号:结果溢出,则转移
    • JNO 标号:结果没有溢出,则转移

​ 假设 a,b相比较,把 a,b看成无符号数和有符号数结果显然不同,故还有以下8条比较指令

  1. a、b是无符号数(4条)

    无符号数不存在大小关系,只存在高低关系。相等:E,高:A,低:B,比如:JNAE的含义是“not A and E”也就是 B,即低于

    • JB/JNAE 标号:a低于b,则转移
    • JBE/JNA 标号:a低于等于b,则转移
    • JA/JNBE 标号:a高于b,则转移
    • JAE/JNB 标号:a高于等于b,则转移
  2. a、b是有符号数(4条)

    有符号数存在大小关系,相等:E,大:G,小:L

    • JL/JNGE 标号:a小于b,则转移
    • JLE/JNG 标号:a小于等于b,则转移
    • JG/JNLE 标号:a大于b,则转移
    • JGE/JNL 标号:a大于等于b,则转移

注意:上节课说过,这些都是有条件转移,也就是转移范围是 -128~+127之间

------------------------------分割线----------------------------------------

书接上回,减法第5条指令

  1. 求负指令:NEG DST ;DST<--0-(DST),根据结果设置6个状态标志
例:在存储器BUFFER单元,有一个16位的带符号数,求该数的绝对值,并把结果放回原处


```assembly
;定义DS段
BUFFER DW ?
;定义代码段
START:  MOV AX, BUFFER
		CMP AX, 0
		JNS EXIT
		NEG AX
		MOV BUFFER, AX
EXIT:	END
```

乘法指令(2条)

乘法指令包括无符号数乘法和与符号数乘法

  • 无符号:MUL SRC
  • 有符号:IMUL SRC

注意

  1. 指令中 DST为隐含的被乘数,存在寄存器 AX
  2. 乘法只有字节乘和字乘,哪种类型是由 SRC的类型决定
  • 字节乘:(AL) * SRC --> AX(AH:AL)高位存余数,地位存商
  • 字乘:(AX) * SRC --> DX:AX

指令执行后只影响 CF、OF,其余状态标志 没定义(值不确定,没意义)

对于无符号数:

CF OF 说明
0 0 高半部积无效(AH/DX=0),只需处理低半部(AL/AX
1 1 高半部有有效积

对于有符号数:

CF OF 说明
0 0 高半部积无效(高半部是低半部积符号位的扩展),只需处理低半部(AL/AX
1 1 高半部有有效积

符号位的扩展:低半部的符号位为0/1,高半部全部扩展为0/1

除法指令(2条)

  1. 无符号除法:DIV SRC

  2. 带符号数除法:IDIV SRC

注意

  1. 对于无符号除法,又分为字节型除法和字型除法,哪种类型是由 SRC的类型决定

    • 字节型除法:被除数隐含在 AX(16位)中,源操作数是8位。商(AL),余数(AH
    • 字型除法:被除数隐含在 DX:AX(32位)中,源操作数是16位。商(AX),余数(DX
  2. 对于带符号数,分为下面4种情况

    被除数 除数 余数
    + + + +
    + - - +
    - + - -
    - - + -

例:将存储器BUFFER1中的字节型无符号二进制数转化为十进制数,并将转化结果一分离BCD数的形式存入BUFFER2与下的单元

分析:字节型无符号二进制数范围是0-255,三位数,所以要用3个字节

;DS段
BUFFER1 DB ?
BUFFER2 DB 3DUP(?)
;CS段
MOV AL, BUFFER1
MOV AH, 0		;字节型,要清零
MOV CL, 10		;除数
DIV CL
MOV BUFFER2, AH	;余数,即个位
MOV AH, 0		;清零
DIV CL
MOV BUFFER2+1, AH	;余数,即十位
MOV BUFFER2+2, AL	;商,即百位

符号扩展指令(2条)

  • CBW ;(AL)-->AX(AH:AL)
  • CWD ;(AX)-->DX:AX

例:求 Y=a*b+c-18,其中 a、b、c是字节型变量

;DS段定义
DATA DB ?
DATB DB ?
DATC DB ?
DATY DB 0
;CS段程序
MOV AX, DATA	;准备乘数a
IMUL DATB		;乘法运算a*b
MOV BX, AX		;把积保存到BX
MOV AL, DATC	;积与DATC类型不一致,不能直接计算
CBW				;调整类型
ADD AX, BX		;再相加
SUB AX, 18		;再进行减法
MOV DATY, AX	;将最终结果送到DATY

BCD数调整指令(6条)

+、-分为分离BCD数和组合BCD数调整

*、÷只有分类BCD数调整

注意

  • +、-、*先运算后调整
  • ÷先调整后运算

加法BCD调整

隐含对AL内容调整

  • 组合:DAA
  • 分离:AAA

例1:计算 56+73

MOV AL, 56H
ADD AL, 73H	;结果:1100 1001
DAA			;调整

调整:高4位和低4位,超过9就加6,结果:1 0010 1001-->0010 1001=29,产生进位使 CF=1,最终结果129

例2:计算 4+8

MOV AL, 04H
ADD AL, 08H	;结果:0000 1100
AAA			;调整

调整:

  1. 低位超过9就加6,高位不变,可能产生进位(AF=1),影响 PSW
  2. 使高4位清零,低4位不变,此时 AX=0002H
  3. AFCFAH,最终结果 AX=0102H

注意::分离BCD码调整指令,又名 ASSII码调整指令,比如上例中 4+8<-->'4'+'8'

减法BCD数调整

隐含对AL内容调整

  • 组合:DAS
  • 分离:AAS

例:计算 31-87

MOV AL, 31H
SUB AL, 87H		;结果:1010 1010,借位1即(CF=1)
DAS				;调整

调整:

  1. 对1010 1010,超过9就减6,结果:0100 0100=44H
  2. 由于借位1,即十进制借了100,故最终结果是44-100=56

乘法BCD数调整

  • 分离:AAM

例:计算 7*8

MOV AL, 07H
MOV BL, 08H
MUL BL		;(AX)=0038H,期望:0506H
AAM			;调整

调整:AX÷10-->商:AH,余数:AL,即 (38H)除以10,商5余6-->0506H(38H=56)

除法BCD数调整

隐含对AL内容调整

  • 分离:AAD

例:计算 27÷4

MOV AX, 0207H
MOV BL, 04H
ADD				;(AH)*10+(AL)-->(AX),即02H*10=14H,14H+07H=1B
DIV BL
posted @ 2023-02-20 19:24  打不死の小强丶  阅读(172)  评论(0编辑  收藏  举报