8086汇编-10寄存器(CPU工作原理)05

#pragma once
/* 10-寄存器(CPU工作原理)05
  段寄存器
    段寄存器就是提供段地址的。8086CPU有4个段寄存器:
        CS、DS、SS、ES                    重点!!!!
            CS    代码段寄存器Code Segment    CS是非常重要的
            DS    数据段寄存器Data Segment        在OD中可以看到很多例如mov eax,Dword ptr ds:[0xABCD1234] 这种汇编代码,这就是在使用ds 段寄存器,去 [] 中的地址中拿数据
            SS    堆栈段寄存器Stack Segment
            ES    附加段寄存器(什么都有的意思,例如前面三个不够用了,就放它这)  Extra Segment

    当8086CPU要访问内存时,由这4个段寄存器提供内存单元的段地址。

  CS和IP
    CS和IP是8086CPU中最关键的寄存器,它们指示了CPU当前要读取指令的地址。
        CS为代码段寄存器;    Code Segment
        IP为指令指针寄存器。Instruction Pointer

        看被转译成十六进制代码时,看内存的时候,上面是低位 下面才是高位,汇编指令会占用3个字节,也就是6位 十六进制的内存 ,例如 B82301 ,汇编指令那里不用看高低位,汇编后面的内存才分高低位.
  
  8086PC工作过程的简要描述
    (1)从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;

    (2)IP = IP + 所读取指令的长度,从而指向下一条指令; (这个IP就相当于偏移!!)             *************** 这里一定要记住,IP 在当前汇编执行后,会自己进行增加值,增加的值就是 我们当前指令的长度.

    (3)执行指令。 转到步骤 (1),重复这个过程。

    在 8086CPU 加电启动或复位后( 即 CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H。

    即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行。

    FFFF0H单元中的指令是8086PC机开机后执行的第一条指令。

        
  CS和IP
    在任何时候,CPU将CS、IP中的内容当作指令的段地址和偏移地址,用它们合成指令的物理地址,到内存中读取指令码,执行。

    如果说,内存中的一段信息曾被CPU执行过的话,那么,它所在的内存单元必然被CS:IP指向过。


  修改CS、IP的指令
    在CPU中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对CPU的控制。    ---- 也就是说,我们只可以对寄存器做一些手脚.

    CPU从何处执行指令是由CS、IP中的内容决定的,程序员可以通过改变CS、IP中的内容来控制CPU执行目标指令。

    我们如何改变CS、IP的值呢?


    8086CPU必须提供相应的指令

    先回想我们如何修改AX中的值?

    mov指令不能用于设置CS、IP的值,
       8086CPU没有提供这样的功能。

    8086CPU为CS、IP提供了另外的指令来改变它们的值:转移指令   也就是jmp ,大家也叫他跳转,当我们使用jmp 指令跳转到 一个地址后,CPU就会在这个地址开始执行代码,一直向下执行,我们知道CS与IP 它们指示了CPU当前要读取
指令的地址,那么我们使用jmp,之后CPU就要读取jmp 处的地址了,也就表示了更改了 CS与IP 与IP的地址!!!!

    mov 指令
    如:mov ax,123

    mov指令可以改变8086CPU大部分寄存器的值,被称为"传送指令"。


    能够通过mov 指令改变CS、IP的值吗?  答案是不能的!!!!

    同时修改CS、IP的内容:
        jmp 段地址:偏移地址
            jmp 2AE3:3  
            jmp 3:0B16                    3:0B16  转换成物理地址等于 00030  这里是向左偏移1位 00030+OB16 == 0B46H    : 符号左面是CS :符号右面是IP

        功能:用指令中给出的段地址修改CS,偏移地址修改IP。


    仅修改IP的内容:

        jmp 某一合法寄存器
            jmp ax   (类似于 mov IP,ax  这里只是个比喻!!!)
            jmp bx
            这个操作相当于  在当前CS的位置 跳转到 偏移多少的位置 ,这个偏移量 保存在寄存器中, 在执行这个汇编代码前,要对 保存偏移量的寄存器进行一次mov 操作,把值丢进去.    例如我想让IP的值为200:
             
            mov ax,200
            jmp ax
            这样就达成了跳转到 偏移为200的位置,IP 也就变成了200.
                
        功能:用寄存器中的值修改IP。


  问题分析:CPU运行的流程
    内存中存放的机器码和对应汇编指令情况: (初始:CS=2000H,IP=0000H)
       
    问题分析结果:
        (1)mov ax,6622    读取后    CS=2000H,IP=0003H
        (2)jmp 1000:3        读取后    CS=1000H,IP=0003H
        (3)mov ax,0000    读取后    CS=1000H,IP=0006H
        (4)mov bx,ax        读取后    CS=1000H,IP=0008H
        (5)jmp bx            读取后    CS=1000H,IP=0000H            有这一步 基本上就死循环了..不信可以自己看看
        (6)mov ax,0123H    读取后    CS=1000H,IP=0003H
        (7)转到第(3)步执行  也就是 mov ax,0000        CS=1000H,IP=0006H      
            我们可以发现,CS只有在 第2步的时候被改变了,相信读者已经找到了规律,指令的执行流程 完全是根据 CS+IP 来执行的.


  代码段
    对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。

    可以将长度为 N( N≤64KB )的一组代码,存在一组地址连续、起始地址为 16的倍数的内存单元中,这段内存是用来存放代码的,从而定义了一个代码段。

        例如:
            mov ax,0000        (B8 00 00)
            add ax,0123        (05 23 01)
            mov bx,ax        (8B D8)
            jmp bx            (FF E3)
        这段长度为 10 字节的字节的指令,存在从123B0H~123B9H的一组内存单元中,我们就可以认为,123B0H~123B9H这段内存单元是用来存放代码的 ,是一个代码段 ,它的段地址为123BH,长度为10字节。
    
    如何使得代码段中的指令被执行呢?

    将一段内存当作代码段,仅仅是我们在编程时的一种安排,CPU 并不会由于这种安排,就自动地将我们定义得代码段中的指令当作指令来执行。
    
    CPU 只认被 CS:IP 指向的内存单元中的内容为指令。
    
    所以要将CS:IP指向所定义的代码段中的第一条指令的首地址。
    
    如刚才的CS = 123BH,IP = 0000H。

  小结
    1、段地址在8086CPU的寄存器中存放。当8086CPU要访问内存时,由段寄存器提供内存单元的段地址。8086CPU有4个段寄存器,其中CS用来存放指令的段地址。

    2、CS存放指令的段地址,IP存放指令的偏移地址。

       8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。

    3、8086CPU的工作过程:
        (1)从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
        (2)IP指向下一条指令;
        (3)执行指令。(转到步骤(1),重复这个过程。)

    4、8086CPU提供转移指令修改CS、IP的内容。

  检测点
    下面的3条指令执行后,CPU几次修改IP?都是在什么时候?最后IP中的值是多少?
        mov ax,bx     第一次修改IP
        sub ax,ax     第二次修改IP
        jmp ax         第三次修改IP ,jmp ax本身就会修改IP 所以这是第四次
        答案:4次修改IP,最后IP的值是 寄存器ax 的值. sub 指令是减法,虽然我们没有学,但是可以科普下, sub ax,ax 等同于 ax = ax-ax ,所以 ax = 0000H ,那么也就说明了最后一次 IP的值是ax 也就是 0000H.


*/

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值