Fork me on GitHub

8086汇编:寄存器与寻址方式概述

8086 计算机系统模型

8086 System Model

通过系统总线,将计算机的各个部分链接在一起。CPU 则是这个体系的核心。

8086 CPU 内部模型:

8086 CPU Model

寄存器

8086 CPU 内部有14个可见的(程序员可操作)的寄存器,均为16位。分别为:AX, BX, CX, DX, SP, BP, SI, DI, IP, FLAG, CS, DS, SS, ES。这14个寄存器从用途上又分为三类:通用寄存器,控制寄存器和段寄存器。

通用寄存器

4个数据寄存器:AX, BX, CX, DX

  • AX (Accumulator):累加寄存器
  • BX (Base):基址寄存器
  • CX (Count):计数寄存器
  • DX (Data):数据寄存器

这4个寄存器又可分为8个独立的8位寄存器:AH, BH, CH, DH, AL, BL, CL, DL。

2个指针寄存器:SP, BP

  • SP (Stack Pointer):堆栈指针寄存器
  • BP (Base Pointer):基址指针寄存器

2个变址寄存器:SI, DI

  • SI (Source Index):源变址寄存器
  • DI (Destination Index):目的变址寄存器

段寄存器

  • CS (Code Segment):代码段寄存器
  • DS (Data Segment):数据段寄存器
  • SS (Stack Segment):堆栈段寄存器
  • ES (Extra Segment):附加段寄存器

控制寄存器

  • IP (Instruction Pointer):指令指针寄存器
  • FLAG:标志寄存器

物理地址与有效地址

物理地址(Physical Address)就是CPU查找内存单元时的一个地址,它是唯一的。内存单元物理地址可由段址和段内的偏移量确定,内存单元在段内的偏移量就叫做有效地址(Effective Address)

8086 CPU内部有20根地址线,其编码区间为:0000H~FFFFFH,所以,它的寻址能力(可直接访问的物理空间)为1M字节(2^20 bits)。但是CPU内部为16位的结构,如果用16位寄存器来访问内存的话,表现出来的寻址能力却只有64K。为了能用16位寄存器来有效地访问1M的存储空间,CPU内部采用了两个16位的地址来合成一个20位的物理地址。最终,CPU就采用下面这种方式来合成一个物理地址:

物理地址 = 段地址 × 16 + 偏移地址

这样的方式用汇编表现出来就是:

段寄存器 : 偏移地址

比如,8086 CPU 要访问物理地址为 12000h(十六进制)的内存单元,就可以把 DS 设为 1000h,把 SI 设为 2000h,然后通过 DS:[SI] 的方式表达,地址加法器就会按照上面的公式算出物理地址 = 1000h × 16 + 2000h = 12000h。

四个段寄存器就组成以下四种表达:

  • CS : IP

段寄存器CS指向存放程序的内存段,IP是用来存放下条待执行的指令在该段的偏移量,把它们合在一起可在该内存段内取到下次要执行的指令。

  • DS : **

段寄存器DS指向数据段,在存取操作数时,由DS和一个偏移量合成就可得到存储单元的物理地址。该偏移量可以是具体数值、符号地址和指针寄存器的值等之一,具体情况将由指令的寻址方式来决定。

  • SS : SP

段寄存器SS指向用于堆栈的内存段,SP是用来指向该堆栈的栈顶,把它们合在一起可访问栈顶单元。另外,当偏移量用到了指针寄存器BP,则其缺省的段寄存器也是SS,并且用BP可访问整个堆栈,不仅仅是只访问栈顶。

  • ES : DI

段寄存器ES指向附加数据段,也用于数据的保存,一般与DS用法类似,在进行串操作时,其目的地址的段寄存器规定为ES

寻址方式

首先,要明确,什么是寻址方式。所谓寻址方式,就是讨论指令中操作数的来源问题

根据操作数的不同来源来分类的话,寻址方式可以分为储存器方式和非储存器方式。下面着重讲 8086/8088 体系下的寻址方式。

8086 CPU 有七种基本的寻址方式:

  • 立即寻址
  • 寄存器寻址
  • 直接寻址
  • 寄存器间接寻址
  • 寄存器相对寻址
  • 基址变址寻址
  • 相对基址变址寻址

其中,前两种方式属于非储存器寻址方式,后五种属于储存器寻址方式。除了这些基本寻址方式,还有一些其它的寻址方式,如固定寻址、I/O端口寻址等,这些不会重点介绍。

为了总结方便,我费尽精力做了一个表格:

寻址方式 指令特点 举个栗子 注意
立即寻址 用立即数给寄存器赋值 mov ax, 1234h
寄存器寻址 源操作数为寄存器 (1) mov num, ax
(2) mov ax, bx
直接寻址 括号内一个立即数 (1) mov dx, [1000h]
(2) mov es:[1000h], dx
使用DS作为缺省段寄存器
寄存器间接寻址 括号内一个基址或变址寄存器(SI,DI,BX,BP) (1) mov dx, [di]
(2) mov [bp], cx
若有效地址在SI,DIBX中,
则以DS作为缺省段寄存器;
若有效地址在BP中,
则以SS作为缺省段寄存器
寄存器相对寻址 括号内一个基址或变址寄存器(SI,DI,BX,BP)+
一个立即数
(1) mov ax, [bx+16]
(2) mov ax, 16[bx]
(3) mov es:[bx+5], al
SI,DIBX作为有效地址的一部分,
则以DS作为缺省段寄存器;
BP作为有效地址的一部分,
则以SS作为缺省段寄存器
基址变址寻址 括号内一个基址寄存器(BX,BP)+
一个变址寄存器(SI,DI)
(1) mov ax, [bx+si]
(2) mov ax, [si][bx]
(3) mov ds:[bp+si], al
SI,DIBX作为有效地址的一部分,
则以DS作为缺省段寄存器;
BP作为有效地址的一部分,
则以SS作为缺省段寄存器
相对基址变址寻址 括号内一个基址寄存器(BX,BP)+
一个变址寄存器(SI,DI)+
一个立即数
(1) mov ax, [bx+di+10h]
(2) mov ax, 10h[bx+di]
(3) mov ax, 10h[bx][di]
(4) mov ax, 10h[di][bx]
SI,DIBX作为有效地址的一部分,
则以DS作为缺省段寄存器;
BP作为有效地址的一部分,
则以SS作为缺省段寄存器
-------------------------------- 全文完 感谢您的阅读 --------------------------------
「写的那么辛苦,连一块钱都不打赏吗/(ㄒoㄒ)/~~」