80×86 实模式入门(1): 基础概念

正文索引 [隐藏]

80x86 实模式入门(1)—— 基础概念

一、名词解释

1. 实模式

实模式:操作系统启动前,此时权限最高

  • CPU 复位或加电时,处理器以实模式工作
  • 此时所有段都是可以读写的
  • 不支持硬件多任务切换,所有指令在同一环境下进行

2. 计算机中的数据存储方式

  • 存储

  • 存储器以 byte (1 byte = 8 bits) 为单位存储信息
  • 每个字节有一个地址,使用二进制数表示
  • 字长为16位时,一个字要占用相继两个字节
    • 低位字节存入低地址,高位字节存入高地址
    • 以偶地址访问存储器
    • 字单元地址用其低地址表示
  • 寻址

  • 存储器结构
    • 存储器有 20 根地址线,最大物理空间 2^20 = 1024k = 1 M = 1048576,地址范围 00000H ~ FFFFFH
    • 小段:每 16 个字节一小段,共有 64 k 个小段 ( 16 * 64 k = 1 M)
    • 段:由段寄存器控制数据存取,大小不固定,但是段基地址必须是某个小段的起始地址
  • 存储器分段:段起始地址必须是某一小段的首地址,大小可以是 64 K 范围内任意字节
    • 物理地址:每个存储单元唯一的 20 位地址,物理地址 = 10 H * 段地址+ 偏移地址
    • 段基地址: 就是段首的物理地址,段起始地址(20 位)= 10 H * 段地址(16 位)
    • 偏移地址:段内相对于段内起始地址的偏移量(16 位),又称为有效地址
    • 汇编指令需要给出的是逻辑地址(段地址:偏移地址),然后 CPU 自动计算物理地址(注意实模式和保护模式计算方法不一样)

3. 寄存器

​ 所谓寄存器,本质其实是一组在 CPU 中 的快速存储单元,大体上作用有两个:

  1. 快速运算,实现四则运算、比较、位操作
  2. 地址寻找,一般指向存储器的某个位置,和 C 语言中的指针作用非常相似(而且有寄存器名字中干脆直接含有 Pointer,比如 IP)

  • 数据寄存器:数据运算

    • AX:乘除指令;I/O 指令使用 AH(AX 高位)、AL(AX低位)
    • BX:基址寄存
    • CX:计数
    • DX:和 AX 联合使用处理双字长运算(AX 低位,DX 高位);I/O 操作存放端口地址
  • 标志寄存器:数据运算特征

    FLAGS: 16 位标志寄存器

    • OF:Overflow Flag, 溢出标志,溢出为 1,反之为 0
    • DF:Direction Flag, 方向标志
    • 用于控制串操作,指示串操作时操作数地址的增减方向
    • DF 为 1 时,串操作后 SI,DI 自动减量
    • DF 为 0 时,串操作后 SI,DI 自动增量
    • IF:Interrupt Flag, 中断标志
    • IF 为 1, 允许 CPU 响应 INT R(外部可屏蔽中断请求)
    • IF 为 0, 禁止响应 INT R
    • TF:Trap Flag, 陷阱标志
    • TF 为 1,CPU 处于单步调试
    • TF 为 0,CPU 处于正常工作
    • SF:Sign Flag, 符号标志,运算结果为正为 0,反之为 1
    • ZF:Zero Flag, 零标志,运算结果为零时为 1,否则为 0
    • AF:Auxiliary Carry Flag, 辅助进位标志,低半字节(最低 4 位)向高半字节,D3 -> D4 有进位为 1,否则为 0
    • PF:Parity Flag, 奇偶标志,运算结果的低 8 位中,“1” 的个数为偶数时为 1, 否则为 0
    • CF:Carry Flag, 进位标志,最高位产生进位或借位时为 1,否则为 0
  • 指针和变址寄存器:IP,SP,BP,SI,DI

    • SP:Stack Pointer,一般配合 SS 取栈中的数据
    • BP:Stack Base Pointer,一般存放偏移量配合 SS 取数据
    • SI:Source Index,一般存放偏移量配合 DS 取数据
    • DI:Destination Index,一般存放偏移量配合 ES 取数据
    • BP、SI、DI 也可以灵活使用,不一定要和默认段寄存器配合
  • 控制寄存器:IP

    • IP:Instruction Pointer,始终指向下一条即将执行的指令首地址,是程序运行位置的指针,和 CS 搭配使用
  • 段寄存器:CS,SS,DS,ES

    • CS:Code Segment Register
    • SS:Stack Segment Register
    • DS:Data Segment Register
    • ES:Extra Data Segment Register
    • 用于给出各种数据的地址

二、寻址方式

​ 这里介绍下如何从存储器中得到想要的值、如何把数据存储在存储器中,这就离不开地址寄存器了。

​ 不过首先要介绍下 MOV 指令,作为最常用到的数据移动指令,使用形式是:MOV DST, SRC,就是将 SRC 中的数据复制到 DST 中,SRC 和 DST 称为操作数,一般可以表示数据或者数据地址,还有其他的数据操作之后的指令系统会详细介绍。

1. 操作数表示

操作数段基地址

操作类型 约定段寄存器 允许指定的段寄存器 偏移量
指令 CS IP
堆栈操作 SS SP
普通变量 DS ES,SS,CS EA
字符串指令 SRC DS ES,SS,CS SI
字符串指令 DST ES DI
BP 用作基址寄存器 SS DS、ES、CS EA

操作数偏移地址

  • 位移量:是指令中指定 的一个8位、16位或32位的数,它不是立即数 而是存储单元地址相对于某处的位移量
  • 基址:BP、BX,通常用于指向数组首地址
  • 变址:SI、DI,通常用于指向数组中的某个元素位置
  • 比例因子:可为 1,2,4,8,对应数组元素字节数(386 之后机型)

举例

比如 SRC 存储器数据端中的某个数组(数组首地址为 BP)的某个元素(第 7 个元素),可以表示为:DS:BP[SI],当然这里的 SI 为 7,对 SI 进行加减操作就可以取到不同的元素

2. 数据操作寻址方式

  1. 立即寻址
    • 直接写个立即数
    • 只能用于 SRC
    • MOV AX, 5
  2. 寄存器寻址
    • 操作数在指定寄存器(AH AL BH BL CH CL DH DL)中
    • 禁止使用 MOV 改变 CS
    • MOV BX, AX
  3. 寄存器直接寻址
    • 段基地址用段寄存器指定,偏移地址手动给出,用 [] 装好
    • 如果缺省段寄存器,将使用默认段寄存器
    • MOV BX, DS:[2100H]; 将数据段中 2100H 处的数据复制到 BX
    • MOV BX, A; A 在数据段已经定义的情况下可以直接写 A,这属于一种伪操作,汇编工具会完成转化
  4. 寄存器间接寻址
    • 寄存器 BX、BP、SI、DI 中存的是偏移地址,使用 [] 装好
    • MOV BX, DS:[SI]; 如果 SI 中存的是 2100H 就和 3 中的例子效果一样
  5. 寄存器相对寻址
    • 数组首地址已经给出,寄存器中装的是偏移量,一般用 BX、BP、SI、DI
    • MOV BX, ARRAY[SI]; ARRAY 已经定义在数据段
  6. 基址变址寻址
    • 偏移地址(基址,使用 BX,BP)、偏移量(变址,使用 SI、DI)都由寄存器表示
    • MOV AX, [BX][SI]
  7. 相对基址变址
    • 综合 5、6
    • MOV AX, ARRAY[BX][SI]
  8. 比例变址(386 以上)
    • MOV EAX, NUM[ESI * 8]
  9. 基址比例变址(386 以上)
    • MOV AX, [BX][SI * 2]
  10. 相对基址比例变址(386 以上)
    • MOV AX, NUM [BX][SI*2]

8,9,10 主要是为了实现数组跳跃读数,比如只要数组的偶数位元素就可以给变址 2