8086寄存器

来源:互联网 发布:怀孕食谱软件 编辑:程序博客网 时间:2024/05/16 02:42

概念

CPU访问内存(物理地址): 
物理地址 = 基地址+偏移地址
基地址是由端地址左移4位生成的,然后在寄存中和偏移地址在地址加法器中相加构成真正的物理地址。


段:

在编程时,将一段连续的内存单元看成是一个段,通过将一个段地址左移4位形成基地址(段起始地址),再通过偏移地址定位到段中的内存单元。
段的起始地址肯定是16的整倍数(段地址左移4位),一个段内的内存单元只能通过偏移来访问。
一个段的长度为2^16也就是64K。段又分为数据段、代码段、堆栈段。

栈:
特殊规则的段,即一块具有特殊访问规则的连续的内存单元。PUSH和POP

寄存器

通用寄存器:

数据寄存器
AX:(accumulator)累加寄存器
BX:(Base)基址寄存器
CX:(conut)计数器寄存器
DX:(data)数据寄存器


解释:
(1)这4个16位寄存器可以分为2个独立的高8位寄存器和低8位寄存器,例如:MOV AH 10H ;不管AL是什么东西
MOV AX, 1234H ;AX寄存器的值为0x1234
MOV AH, 56H ;AX寄存器的值为0x5634
MOV AL, 78H ;AX寄存器的值为0x5678


(2)AX乘除法运算
(a)除法
(a.1)除数是8位的
被除数一定是16位的,并且一定放在AX寄存器内。
当除法执行完以后,AL保存此次除法操作的商,AH保存此次除法操作的余数
(a.2)除数是16位的
被除数一定是32位的,因为AX是16位的,需要DX寄存器配合,DX存放32位数的高16位,AX存放32位数的低16位
当除法执行完以后,AX保存此次除法操作的商,DX保存此次除法操作的余数

例如:
MOV DX, 0H
MOV AX, 8H
MOV BX, 2H ;除数为16位
DIV BX ;执行除法,结果(DX<<16 + AX)


(b)乘法:2个乘数要么都是8位的,要么都是16位的

(b.1)2个乘数是8位的
一个默认放在AL中,另一个放在其他寄存器或内存单元中。
默认的乘法运算结果存放在AX中


(b.2)乘数是16位的
一个默认放在AX中,另一个放在16位的其他寄存器或内存单元中。
默认的乘法运算结果高16位存放在DX中,低16位存放在AX中。


例如:
MOV AX, 8H ;乘数为16位
MOV BX, 2H ;另一个乘数
MOV DX, 0H ;清空DX寄存器
MUL BX ;执行乘法,结果(DX<<16 + AX)


(3)BX寄存器
(a)可以存放数据
(b)作为偏移地址使用,通过<段地址:[BX]>的方式来完成寻址
例如:
MOV BX, 5H
MOV AH,11H

MOV AH,[BX] ; 改变AX的值为偏移地址为BX中的值所代表的内存单元


(4)CX寄存器
(a)作为数据寄存器来存放数据
(b)当汇编指令中使用LOOP指令时,可以通过CX来指定需要循环的次数。
LOOP所做的事情:令CX寄存器自动减一;判断CX寄存器是否为0,为0则跳出循环,不为0则继续执行循环中的指令。例如:(输出白底蓝字的ABCDE)
MOV AX, 0B800H
MOV DS,AX ;使用 80x25 彩色字符模式,内存地址 0xB8000 - 0xBFFFFF ????
MOV BX,0H ;偏移地址为0,即从0xB8000开始
MOV CX,5H ;循环次数
MOV DX,41H ;'A'
MOV AX,01110001B;显示白底蓝字 ????
S:
MOV [BX],DX  ;显示 ASCII 字符
ADD BX,1
MOV [BX],AX ;设置字符显示属性
ADD BX,1
ADD DX,1 ;
LOOP S
(5)DX
(a)作为数据寄存器存放数据
(b)和AX搭配进行乘除法运算


指针寄存器:

SP:(Stack pointer)堆栈指针寄存器
BP:(base pointer)基指针寄存器
解释
(1)BP寄存器
(a)作为通用寄存器可以暂存数据,但不能分割成2个独立的8位寄存器
(b)当以[BP]方式访问内存单元时,默认的段寄存器为SS,例如:
MOV BP,0H
MOV AX,[BP] ;将SS:[BP]代表的内存单元移入AX寄存器
MOV AX,DS:[BP] ;将DS:[BP]代表的内存单元移入AX寄存器


 SP 寄存器实质上必须和 SS 段寄存器一起使用,所以,我将会把 SP 寄存器留到后面和 SS 段寄存器一起作介绍

注:在8086CPU中只有4个寄存器可以使用[], 分别为 BX,BP,SI,DI


变址寄存器:

SI:(source index)源变址寄存器
DI:(destination index)目的变址寄存器
解释:
(1)作为通用寄存器可以暂存数据,但不能分割成2个独立的8位寄存器
(2)作为存储器指针使用,用于存放某个存储单元地址的偏移,或者是用于某组存储单元开始地址的偏移。


控制寄存器:

IP:(instruction pointer)指令指针寄存器
FLAG:标志寄存器上


段寄存器:

CS:(code segment)代码段寄存器
DS:(data segment)数据段寄存器
SS:(stack segment)堆栈段寄存器
ES:(extra segment)附加段寄存器


由于寄存器和段寄存器是协作使用的,下面进行合并讲解
(1)CS寄存器和IP寄存器
CS:IP两个寄存器指示了当前cpu将要读取的指令的地址。当一个可执行文件加载到内存中以后,CS:IP  两个寄存器便指向了这个可执行文件的起始地址,然后CPU就可以从这个起始地址开始往下读取指令,当读取完指令后,CS:IP  将会自动的改变,基本上是改变IP,从而指向下一条要读取的指令,这样就可以执行这个可执行文件了。


最后再对  CS:IP  总结一下:
(a)你想让  CPU  执行哪行指令,你就让  CS:IP  指向保存有指令的那块内存即可。
(b)任何时候,CS:IP  指向的地址中的内容都是  CPU  当前执行的指令。


CS:IP的遐想:
从上面关于CS:IP的介绍中,我们可以大胆的猜想,我们只需要通过手动的改变  CS:IP  所指向的内存地址,让CS:IP指向我们另外的代码,那么我们就可以让  CPU  执行我们自己指定的代码了 。即可以通过修改CS:IP来达到我们想要让CPU干什么它就干什么的目的 。
(2)SS寄存器和SP寄存器
在任何时刻,SS:SP  都是指向栈顶元素 。SS为栈为栈的段地址,SP为指向栈顶的偏移地址
其实关于栈的使用还是比较简单的,但是要注意的是  8086  CPU  并不会保证我们对栈的操作会不会越界 。
所以我们在使用栈的时候需要特别注意栈的越界问题 。


当使用  PUSH 指令向栈中压入 1 个字节单元时,SP = SP - 1;即栈顶元素会发生变化;
而当使用  PUSH 指令向栈中压入  2 个字节的字单元时,SP = SP – 2 ;即栈顶元素也要发生变化;
当使用  POP 指令从栈中弹出 1 个字节单元时, SP = SP + 1;即栈顶元素会发生变化;
当使用  POP 指令从栈中弹出 2 个字节单元的字单元时, SP = SP + 2 ;即栈顶元素会发生变化


注:在编程中创建栈时,栈的大小在创建的时候就固定好了,由栈底向栈顶方向内存地址是递减的。
因为PUSH时栈增长而SP--,此时内存单元的地址为SS:[SP],必然小于前一个内存单元的地址咯。


例子:
ASSUME CS:CODES


CODES SEGMENT

START:
   
   MOV AX,1000H;首先是定义好栈的段地址
   MOV SS,AX    
   MOV AX,10H ;再定义好栈的长度(初始时刻的栈顶偏移地址即栈的长度)
   MOV SP,AX
   
   MOV AX,0001H
   PUSH AX
   MOV AX,0002H
   PUSH AX
   MOV AX,0003H
   PUSH AX
   MOV AX,0004H
   PUSH AX
   MOV AX,0005H
   PUSH AX
   
   POP AX
   POP AX
   POP AX
   POP AX
   POP AX
   
   
   MOV AH,4CH
   INT 21H
CODES ENDS
   END START


(3)DS寄存器和ES寄存器
都属于段寄存器,存放的都是某个段的地址。DS寄存器通常存放的是要访问的数据的段地址。
ES寄存器是附加寄存器,当扩展段来使用。


注:寄存器中只有BX、BP、SI、DI可以使用[]方式寻址,当以[]方式寻址时BP默认的段为SS,BX、SI、DI寄存器默认指向的段为DS
例子:DS段寄存器DEMO,分别将1,2,3,4,5 写入到以(0x1000<<+[BX])开始的物理内存单元中。


ASSUME CS :CODES


CODES SEGMENT


START:
MOV AX,1000H
MOV DS,AX
MOV AL,1
MOV BX,0


MOV CX,5 ;循环此时
S:
MOV [BX],AL ;[bx]默认使用的段寄存器为DS寄存器
INC AL
INC BX
LOOP S


MOV AH,4CH
INT 21H
CODES ENDS

END START


注:8086不支持直接将一个数据送入段寄存器
错误:MOV DS,1000H
正确方式:MOV AX,1000H
MOV DS,AX


标志寄存器FLAG

FLAG寄存器中,每一位都表示不同状态。FLAG寄存器中存储的信息通常称为程序状态字(PSW)

CF(carry flag)进位标志位,有计算时有进位则为1,否则为0
PF(parity falg)奇偶标志位,执行相关指令后,判断结果的bit位1的个数,偶数则为1,奇数则为0 
AF(Auxiliary  Carry  FLag)辅助进位标志位,字节操作时低半字节向高半字节借位或进位时为1,或者字操作时低字节向高字节借位或进位时为1
ZF(ZERO FLAG)相关指令执行完毕后,若结果为0则zf标志为1,否则为0
SF(SIGN FLAG)符号标志位,相关指令执行后,若结果为负数则为1,否则为0
TF(TRAP FLAG)追踪标志,调试时使用,当标志为1时,cpu进入单步方式
IF(Interrupt-Enable  FLag)中断使能标志,决定cpu是否能响应外部可屏蔽中断请求,为1则能,为0则不能
DF(Direction flag)方向标志,用于在串处理指令中,控制每次操作后SI和DI是自增还是自减。标志为0则SI++/DI++,为1则SI--/DI--
OF(OVERFLOW FLAG)溢出标志,记录有符号计算的结果是否发生了溢出,若发生了溢出则标志位为1,否则为0。


0 0
原创粉丝点击