寄存器概述

8086CPU有14个寄存器 它们的名称为:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。

通用寄存器

  1. 8086CPU所有的寄存器都是16位的,可以存放两个字节。
  2. AX,BX,CX,DX通常用来存放一般性数据被称为通用寄存器。
  3. AX为例,寄存器的逻辑结构。

image.png
数据:20000(4E20H)
二进制表示:0100 1110 0010 0000

  1. 为保证8位寄存器的兼容,分为两个独立的8为寄存器使用:
    1. AX可分为AH和AL;
    2. BX可分为BH和BL;
    3. CX可分为XH和CL;
    4. DX可分为DH和DL;

image.png
AH:78(4EH)
AL:32(20H)

几条汇编指令

mov ax,8226H
mov bx,8226H
add ax,bx ax=044CH

mov ah,0
mov al,C5H
add al,93H ax=0058H

进制位不能在8位寄存器中保存,但是CPU不是真的丢弃这个进制值。

物理地址

  1. CPU访问内存单元时要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间。
  2. 这唯一的地址称为物理地址。
  3. 16位结构的CPU:
    1. 运算器一次最多可以处理16位的数据。
    2. 寄存器的最大宽度为16位。
    3. 寄存器和运算器之间的通路是16位。

      8086CPU给出物理地址的方法

      寄存器 - 图3
  • 8086CPU读写内存时:
    • CPU中的相关部件提供了两个16位的地址,一个称为段地址,另一个称为偏移地址;
    • 段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
    • 地址加法器将两个16为地址合并成一个20为的地址;
  • 地址加法器合成物理地址的方法:

    • 物理地址=段地址✖16+偏移地址

      段的概念

  • 内存并没有分段,段的划分来自于CPU,由于8086CPU用“段地址✖16+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。

  • 在编程时可以根据需要,将若干连续地址的内存单元看做一个段,用“段地址✖16”定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。

    段寄存器

  • 段寄存器就是提供段地址的。

    • 8086CPU有4个段寄存器:
      • CS、DS、SS、ES
  • 当8086CPU要访问内存时,由这四个段寄存器提供内存单元的段地址。

    CS&IP

  • CS和和IP是8086CPU中最关键的寄存器,他们指示了CPU当前要读取指令的地址。

    • CS为代码段寄存器
    • IP为指令指针寄存器

8086PC工作过程的简要描述

  1. 从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
  2. IP=IP+所读取指令的长度,从而指向下一条指令;
  3. 执行指令。转到1步骤,重复这个过程。

    代码段

  • 对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。
  • 可以将长度为N(N<=64KB)的一组代码,存在一组地址连续、其实地址为16的倍数的内存单元中,这段内存是用来存放代码的,从而定义了一个代码段。
  • CPU只认被CS:IP指向的内存单元中的内容为指令。

    DEBUG

    R:查看、改变CPU寄存器的内容
    image.png
    D:查看内存中的内容
    image.png
    E:改写内存中的内容
    image.png
    U:将内存中的机器指令翻译成汇编指令
    image.png
    T:执行一条机器指令
    image.png
    A:以汇编指令的格式在内存中写入一条机器指令
    image.png

    内存中字的存储

  • 在0地址处开始存放4E20H

寄存器 - 图10

  • 0号单元是低地址单元,1号单元是高地址单元。
  • 任何两个地址连续的内存单元,N号单元和N+1号单元,可以将他们看成两个内存单元,也可以看成一个地址为N的字单元中的高位字节单元和地位字节单元。

    DS&[address]

  • CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址。

  • 在8086CPU中,内存地址有段地址和偏移地址组成。
  • 8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址。
  • 将al中的数据送入内存单元10000H?

    • mov bx,1000H
    • mov ds,bx
    • mov [0],al

      字的传送

  • 在8086CPU是16为结构,有16根数据线,所以可以一次性传送16为的数据。

写出下面ax,bx,cz的值。其中
10000H 23
10001H 11
10002H 22
10003H 66

  • mov ax,1000H
  • mov ds,ax
  • mov ax,[0]
  • mov bx,[2]
  • mov cx,[1]
  • add bx,[1]
  • add cx,[2]

image.png
写出下面ax,bx,cz的值。其中
10000H 23 34
10001H 11 2c
10002H 22 12
10003H 11 1b

  • mov ax,1000H
  • mov ds,ax
  • mov ax,2C34H
  • mov [0],ax
  • mov bx,[0]
  • sub bx,[2]
  • mov [2],bx

image.png
image.png

mov&add&sub

  • mov指令的几种形式:
    • mov 寄存器,数据 mov ac,2C34H
    • mov 寄存器,寄存器 mov bx,ax
    • mov 寄存器,内存单元 mov ax,[0]
    • mov 内存单元,寄存器 mov [0],ax
    • mov 段寄存器,寄存器 mov ds,ax
    • mov 寄存器,段寄存器 mov ax,ds
  • add和sub指令同mov一样,都有两个操作对象

    数据段

  • 用123B0H~123B9H这个空间来存放数据:

    • 段地址:123BH
    • 长度:10字节 (一个地址指向一个内存单元,一个内存单元用两个16进制表示占1个字节,占8位)

      栈(SS:SP)

  • 栈FILO

  • 8086CPU提供入栈和出栈指令:
    • push
    • pop
  • CPU如何知道当前要执行的指令的位置?
    • 寄存器CS和IP存放着当前指令的段地址和偏移地址
    • 8086CPU中,有两个寄存器:
      • 段寄存器SS 存放栈顶的段地址
      • 寄存器SP 存放栈顶的偏移地址
      • SS:SP指向栈顶元素。
  • 栈顶超界是危险的
  • 在编程时,我们可以根据需要,将一组内存单元定义为一个段。
  • 可以将长度N(N<=2^16)的一组地址连续、起始地址为16倍数的内存单元当做栈使用,从而定义了一个栈段。
  • 我们 将10000H~1FFFFH这段空间当作战,SS=1000H,栈空间大小为64k,栈底部的子单元地址为1000:FFFE。栈空时,SP=0000H。

    总结

  1. CPU访问内存单元时,必须向内存提供内存单元的物理地址。
  2. 8086CPU在内部用段地址和偏移地址移位相加的方法形成最终的物理地址。
  3. 段地址在8086CPU的寄存器中存放。当8086CPU要访问内存是,有段寄存器提供内存单元的段地址。8086CPU有4个段寄存器,CS用来存放指令的段地址。
  4. CS存放指令的段地址,IP存放指令的偏移地址。
  5. 8086机中,任意时刻,CPU将CS:IP指向的内容当做指令执行。
  6. 在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、地地址单元和低8为寄存器相对应。
  7. mov、add、sub是具有两个操作对象的指令。jmp是具有一个操作对象的指令。
  8. 我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。
  9. 我们可以用一个段定义为:数据段、代码段、栈段。