汇编语言笔记:数据传送指令

601 阅读4分钟

汇编语言笔记:数据传送指令

立即数、地址、数据传送到寄存器、存储器、端口号寄存器

  • Reg:寄存器

    • Segreg:段寄存器
  • Mem:存储器

  • Imm:立即数

通用数据传送指令

  • 交换:XCHG
  • 传送:MOV、MOVSX(带符号)、MOVZX(带零扩展)
  • 进出栈:PUSH(进)、POP(出)、PUSHA/PUSHAD(所有通用寄存器进)POPA/POPAD(所有通用寄存器出)

普通传送指令:MOV DST, SRC

具体格式:

MOV Reg/Mem, Reg/Mem/Imm

具体功能:

把源操作数SRC的值赋给目的操作数DST

MOV规定:

  • 两个操作数数据类型相同
  • 两个操作数不能同时为段寄存器
  • 代码段寄存器CS不能为目的操作数
  • 立即数不能直接传给段寄存器
  • 立即数不能作为目的操作数
  • 指令指针IP不能作为MOV指令操作数
  • 两个操作数不能同为存储单元

带符号扩展传送指令:MOVSX DST, SRC

具体格式

  • MOVSX REG1, REG2:

    • REG1为16位时REG2为8位
    • REG1为32位时REG2为16位
  • MOVSX REG32, MEM16:

    • REG32为32位,MEM16为16位

具体功能

将SRC的值符号扩展后赋给DST

eg

入栈指令:PUSH SRC

具体格式:

PUSH data/reg/Segreg/Mem

  • mem允许任何寻址方式,但8086不许立即数寻址

具体功能:

  1. 堆栈指针减2(4)
  2. 寄存器、段寄存器或存储器中的单(双)字数据压入堆栈

eg:

出栈指令:POP DST

具体格式:

POP reg/segreg/mem

  • DST不是立即数或CS即可

具体功能:

  1. 先将栈顶单(双)字元素弹出致某一寄存器、段寄存器(除CS)或存储器
  2. 堆栈指针+2(4)

eg:

所有通用寄存器入栈指令:PUSHA/PUSHAD

功能:

八个通用寄存器的值全部入栈,顺序如下。

image-20221103111334824.png

因为当前元素位置指针SP的值也要入栈,注意入栈的是执行PUSHA前的值。

eg:

所有通用寄存器出栈指令:POPA/POPAD

功能:

当前堆栈中连续的8个(双)字内容出栈给相应通用寄存器。

出栈顺序与入栈反序。

eg:

交换指令:XCHG OPR1,OPR2

具体格式:

  • XCHG REG1,REG2
  • XCHG REG,MEM

功能:

通用寄存器与通用寄存器/内存单元交换。

两个操作数长度必须相同。

累加器专用传送指令

3条指令,仅限于使用AL,AX,EAX ,用于ACC与I/O端口交换数据

寄存器:

  • AL:字节操作
  • AX:字操作
  • EAX:双字操作

输入指令:IN 累加器,端口号

  • 长格式:PORT存放8位端口号
  • 短格式:DX存放16位端口号

注意:I/O端口最多65536个,端口号小于256时都可用,否则必须用短格式。

功能:

从端口读入数据,保存在寄存器中。

如果端口地址在0~255之内,可在IN中直接给出。否则要先存入DX中。

eg:

  • 端口地址:60H

IN AL,60H

  • 端口地址:2F8H
 MOV DX,2F8H
 IN AL,DX

输出指令: OUT 累加器,端口号

换码指令:XLAT (OPR)

若表格首地址的偏移已存入BX/EBX时OPR可省去

功能:

把BX的值作为内存字节数组首地址、下标为AL的数组元素的值传给AL。

给定数组下标AL和数组首地址BX,找对应数组值,再存回AL。

eg:

image-20221103164030643.png

 MOV BX, offset table ;执行后(BX)=0040H
 MOV AL, 3
 XLAT ;执行后(AL)=33H

地址传送指令

有效地址传送寄存器指令:LEA REG16/32, SRC

功能:

把源操作数SRC的有效地址EA送入通用寄存器

:SRC可使用除“立即数寻址”和“寄存器寻址”以外任意寻址方式。

指针送通用寄存器和段寄存器:LDS REG16/32, SRC

LES LFS LGS LSS类同LDS

功能:

(REG16)<-(SRC)单字;然后(DS)<-(SRC+2)单字;

(REG32)<-(SRC)双字;然后(DS)<-(SRC+4)单字;

:SRC只能用“存储器寻址”

eg:

(DS)=3000H,(BX)=1000H,(SI)=019EH

image-20221103170052766.png

 MOV CX,TABLE 
                                         ;(CX)=0D0EH
 LEA BX,[BX+SI+0063H]
                                         ;(BX)=1000H+019EH+0063H=1201H
 LDS SI,[1200H]
                                         ;(DS)=3000H,所以要从下方的块找。
                                           (SI)=(1200H)=0C0DH,             
                                          (DS)=(1200H+2)=([1202H])=0A0BH
 LES DI,[BX] 
                                         ;(ES)=3000H,所以要从上方的块找。
                                          (DI)=([BX])=(1201H)=0302H
                                          (ES)=([BX]+2)=(1203H)=0504H

标志寄存器传送指令

标志送AH指令:LAHF

(AH)<-(FLAGS低8位)

AH送标志寄存器指令:SAHF

:修改标志寄存器低8位

(FLAGS低8位)<-(AH)

标志入栈指令:PUSHF/PUSHFD

  • PUSHF:

    1. (SP)<=(SP)-2
    1. ((SP)+1,(SP))<=(FLAGS)低16位
  • PUSHFD:

    1. (ESP)<=(ESP)-4

    2. VM和RF位清零,其他位不变后32位入栈

      ((ESP)+3,(ESP)+2,(ESP)+1,(ESP))<=(EFLAGS and OFCFFFFH)

标志出栈指令:POPF/POPFD

!:修改FLAGS内容

  • POPF:

    1. (FLAGS)16<=((SP)+1,(SP))
    2. (SP)<=(SP)+2
  • POPFD:

    1. (EFLAGS)32<=((ESP)+3,(ESP)+2,(ESP)+1,(ESP))
    2. (ESP)<=(ESP)+4

类型转换指令

字节转换为字:CBW

(AX)<=将(AL)符号扩展成字

字转换为双字:CWD/CWDE

(DX:AX)或(EAX)<=将(AX)符号扩展成双字;

双字转换为四字:CDQ

(EDX:EAX)<=将(EAX)符号扩展成四字;

字节交换:BSWAP REG32

将32位通用寄存器REG32中四个字节反序:

1、4字节交换,2、3字节交换

eg:

执行前(EDX)=12345678H

执行后(EDX)=78563412H