汇编学习笔记(15) - 80386 从16位32位

简述

  80386相比于8086 地址线从20位扩展为32位,这意味着80386可以最多访问4G的内存,同时所有的寄存器都扩展为32位寄存器,80386扩展了原来的寄存器,增加了一些新的指令,并增加了新的寄存器

  80386的寄存器主要分如下几类:通用寄存器,段寄存器,指令寄存器,标志位寄存器,系统地址寄存器,控制寄存器,测试寄存器,调试寄存器。

  80386的指令集也大多集成8086的指令集,只是将其扩充为32位寄存器而已。

寄存器

通用寄存器

通用寄存器是在8086的8个通用寄存器(AX,BX,CX,DX,BP,SP,SI,DI)的基础上将其扩展了32位寄存器,名称为在原先的名字前面加了个E, 分别为EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI

原先的16位和8位寄存器即 AX, AL ,AH等都还是可以使用的,同时AX 是EAX的低16位,类似于 AX和AL的关系,EAX的高16位无法单独使用。

 

段寄存器

原先的段寄存器保持不变还是16位,同时增加了FS 和 GS两个新的段寄存器(这两寄存器的全称是啥没查到)

 

指针寄存器

扩展为32位,改名为EIP,IP仍然有效,是EIP的低16位

 

标记寄存器

标志寄存器也扩展为32位,并层架如下四个标志位

    IO 特权(IOPL): 当执行IO指令的时候需要IO的特权级小于等于此标志位,占2位

    嵌套任务标志(NT): 用来指示中断返回指令 IRET的工作方式

    重启标志(RF): 与故障和调试有关

    虚拟8086标志(VM): 表示当前工作在虚拟8086模式下

 

控制寄存器

R0:


PG: 分页控制
  PG=1: 启用内存的分页管理模式
  PG=0: 禁用内存的分页管理模式

PE: 分段控制
  PE=1: 启用内存的分段管理模式, 同时进入保护模式
  PE=0: 禁用内存的分段管理模式, 同时进入实模式

MP: 算数存在位
EM: 模拟位
EM=0: 硬件执行浮点指令运算
EM=1: 软件模拟浮点执行运算
TS: 任务切换位
ET: 扩展位

 

R1: 保留未使用

R2: 缺页中断时存储缺的页的地址

R3: 页目录的地址,只能用前20位,后20位必须为0,所以是4K对齐的

 

系统地址寄存器

先简单介绍一下,在下一章会详细介绍他们

GDTR: 全局表描述符表寄存器

  48位,存放全局段描述符表的地址,前32位存放基地址,后16位是表界限,单位1字节。  

LDTR: 局部表描述符表寄存器

  16位,存放了一个指向GDT的选择子,这个选择子指向的段描述符就描述了局部描述表的位置

IDTR: 中断描述符表寄存器

  48位,存放中断描述符表的地址,前32位存放基地址,后16位是表界限,单位1字节。

TR: 任务状态字寄存器

  16位,存放了一个指向GDT的选择子,这个选择子指向的段描述符就描述了TSS的位置

 

测试寄存器,调试寄存器

  这些寄存器在之后介绍

 

寻址方式的扩展

  8086的寻址方式还是都支持,并做了一些扩展,主要是内存寻址方面

  [内存寻址公式] = [基址寄存器 + 变址寄存器 * 比例因子(可以是 1,2,4,8) + 常数]

  1. 3个元素可以任意搭配,任选其一,任选其二,或都用

  2. 基址寄存器不在局限于 EBX(BX)/EBP(BP), 可以是8个通用寄存器的任意一个

  3. 变址寄存器不在局限于 ESI(SI)/EDI(DI), 可以是除ESP寄存器外剩余的7个通用寄存器的任意一个

  4. 变址寄存器可以乘上一个比例因子,只能是 1 2 4 8 中的一个

 

指令

所有8086的指令都还支持,并且将其扩充为支持32位寄存器。其中还增加了部分指令以增强功能

  

MOVSX,MOVZX

    是MOV指令的高级版,相比与MOV 指令他们能支持不同长度数据的复制比如 MOVSX AX, AL

    MOVSX和MOVZX的不同之处是多出来的数据位的填充方式, SX填充为原操作数的符号位, ZX填充0,所以目的操作数的位宽不能小于源操作数

    举例:

      mov dl,92h

      movsx ax, dl ; ax= ff92h

      movzx ax, dl ; ax=0092h

 

PUSHA, POPA, PUSHAD, POPAD

    PUSHA:  8个16位通用寄存器入栈

    POPA:     8个16位通用寄存器出栈

    PUSHAD:  8个32位通用寄存器入栈

    POPAD:  8个32位通用寄存器出栈

    

LFS、LGS、LSS

    地址传送指令LEA的扩展版本,之前有LDS, LES,这次新增了LFS、LGS、LSS, 主要就是将段地址存到了不同的段寄存器中

 

PUSHFD、POPFD

    32位标记寄存器的出栈入栈,是PUSHF和POPF的扩展指令

  

LODSD、STOSD

    字符串指令的扩展板,支持32位双字节的比较,和LODSB、LODSW等是一个系列的函数,只不过扩展为32位。

 

ENTER、LEAVE

    在NASM汇编阅读笔记中介绍过,主要是做一些堆栈平衡的功能和预留堆栈的作用

 

SETXX系列

    条件设置指令

    格式: SETXX  OPRD1

    其中的XX是条件的意思,比如SETZ, SETNZ, SETA等等,和条件转跳指令JXXX(JZ,JNZ,JA,JB)等是一样的逻辑,只不过条件专挑是满足指令转跳,不满指令啥也不做,

    而条件设置呢就是满足条件设置 OPRD1的值为1 ,不满足则设OPRD1的值为2

  

BT、BTC、BTR、BTS

    位操作指令

    格式: BT OPRD1, OPRD2 

    BT 位测试, 影响标志位
    BTC 位测试并取反
    BTR 位测试并复位 即设置为0
    BTS 位测试并置位 即设置为1

    OPRD1是寄存器寄存器的情况

      那个测试位号 是 OPRD2/ OPRD1 寄存器的长度的余数,所以就不会出现超出范围的情况
      BT AX, 1 那么就是测试1号位
      BT AX, 17 因为AX总共16位所以测17 肯定超过范围,所以实际测试的是 17%16 =1 所有还是1号位


    OPRD1是内存地址的情况

      BT [word 1234], 17 那么实际测试的 [1234+ 17/16 = 1235 ] 的 第 17%16 = 1 位的内存     

BSF、BSR

  位扫描指令

  格式: BSF OPRD1, OPRD2

  扫描OPRD2并把扫描到的第一个为1的位的位号 送到OPRD1

  BSF顺向未扫描,从右向左
  BSR 逆向位扫描 ,从左向右
  影响标志位ZF

LOCK

内存锁前缀

格式: LOCK 其他指令

保证目的操作数的内存地址(目的操作数必须是内存地址,不能是寄存器)的院子操作,用于多处理器同步的
只能用于以下指令
1. XCHG
2. 加减指令:   ADD,ADC,INC,SUB,SBB,DEC,NEG
3. 逻辑运算:  OR, AND,XOR,NOT
4. 位测试:      BT,BTS,BTR,BTC

  

 

 

 

 

 

   

 

posted @ 2020-02-18 00:48  蹦蹦骑士  阅读(1137)  评论(0编辑  收藏  举报