赞
踩
不同的CPU,寄存器的个数、结构是不相同的。
8086CPU有14个寄存器:AX, BX, CX, DX, SI, DI, SP, BP, IP, CS, SS, DS, ES, PSW。
8086CPU的所有寄存器都是16位的,可以存放两个字节。
AX、BX、CX、DX,4个寄存器通常用来存放一般性的数据,称为通用寄存器。
这4个寄存器都可以分为2个可独立使用的8位寄存器来用:
AX可分为AH和AL;
BX可分为BH和BL;
CX可分为CH和CL;
DX可分为DH和DL;
字节,记为byte;
字,记为word;一个字由2个字节组成;
使用emu8086模拟器执行一条汇编指令;
mov ax, 18
18转换为16进制为12;
执行之后把12存入AX的低字节;
mov ax, 18
mov bx, 37
add ax, 8
add ax, bx
程序开始执行;所有寄存器为0;
IP为0;
执行完第一条指令,把12H放入AX;
IP变为0003,指向下一条将要执行的指令;
执行完第二条指令,把25H放入BX;
IP随之改变;
执行完第三条指令,AX内容变为1AH;
IP随之改变;
执行完第四条指令,AX内容变为3FH;
CS和IP寄存器指示了CPU当前要读取指令的地址。CS为代码段寄存器,IP为指令指针寄存器。
段的概念
内存并没有分段,段的划分来自于CPU。由于8086CPU用“基础地址(段地址*16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。
段地址*16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址为16位,16位的寻址能力为64KB,所以一个段的长度最大为64KB。
偏移地址16位,变化范围为0-FFFFH,仅用偏移地址来寻址最多可寻64KB个内存单元。
比如给定段地址1000H,用偏移地址寻址,CPU的寻址范围为:10000H-1FFFFH。
在8086中,任意时刻,设CS寄存器中的内容为M,IP寄存器中的内容为N,8086CPU将从内存M*16+N单元开始,读取一条指令并执行;
也表述为:8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行;
能够改变CS、IP的内容的指令统称为转移指令。例如jmp指令;
====
mov ax, 18
mov bx, 37
add ax, 8
add ax, bx
在emu8086中查看 基础地址+偏移地址=物理地址
指令存放于内存,起始地址为0100:0000;
CS寄存器初始值为0100;
第二条指令存放起始地址为0100:0003;
第三条指令存放起始地址为0100:0006;
第四条指令存放起始地址为0100:0009;
在emu8086中默认代码段初始值为0100:0000;
效果如前图;
内存单元是字节单元,一个字要用两个地址连续的内存单元来存放,低位字节存放在低地址单元中,高位字节存放在高地址单元中。
8086CPU中有一个DS寄存器,通常用来存放要访问数据的段地址。
如果要读取10000H单元的内容,可以用如下的程序段:
mov bx, 1000H
mov ds, bx
mov al, [0]
上面三条指令将10000H(1000:0)中的数据读到al中;
mov指令可以完成的传送:
将数据直接送入寄存器;
将一个寄存器中的内容送入另一个寄存器;
将一个内存单元中的内容送入一个寄存器;
汇编语言使用 [ ......] 表示一个内存单元;中括号中的数字表示内存单元的偏移地址;
只有偏移地址不能定位一个内存单元,内存单元的段地址是多少?
指令执行时,8086CPU自动取ds中的数据为内存单元的段地址;
下面用emu8086仿真执行以下代码;
mov ax, 1000H
mov ds,ax
mov ax, 11316
mov [0], ax
图1,程序开始执行,所有寄存器为0;DS寄存器在emu8086中初始默认为0100;
图2,执行完第一条指令,1000H放入AX中;
图3,执行完第二条指令, DS寄存器内容变为1000H;
图4,执行完第三条指令,2C34H放入AX中;此时DS是1000H;
图5,执行完第四条指令,指令是把AX中的内容,即2C34H放入偏移地址0000处,数据段地址是从DS取;即把2C34H放入1000:0000处;执行完之后面板看不到内容,因为此时面板只能看到仿真内存的起始部分;
图6,在面板仿真内存的顶部,手动输入内存地址1000:0000,回车;仿真内存定位到1000:0000处;看一下34和2C已被放入相应单元;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。