• 汇编语言——寄存器(CPU的工作原理 ax,bx,cx,dx通用寄存器 cs代码段寄存器)


    寄存器

    一个典型的CPU由运算器、控制器、寄存器等器件组成,这些器件靠内部总线相连。(外部总线是上一篇博客说的内存总线,数据总线,控制总线)

    • 内部总线实现CPU内部各个器件之间的联系。
    • 外部总线实现CPU和主板上其它器件的联系。

    CPU中主要的部件是寄存器,寄存器是CPU中我们可以使用指令读写的部件(通过改变各种寄存器的内容来实现对CPU的控制)

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

    1、通用寄存器

    a.简介

    8086CPU所有的寄存器都是16位的,可以存放两个字节。(1Byte=8bit)
    AX、BX、CX、DX 通常用来存放一般性数据被称为通用寄存器。

    一个16位寄存器所能存储的数据的最大值为:216-1

    示例:

    数据:20000
    二进制表示:0100111000100000
    在寄存器AX中的存储:

    四个寄存器都可以分为两个独立的8位寄存器使用。
    AX可以分为AH和AL;
    BX可以分为BH和BL;CX可以分为CH和CL;
    DX可以分为DH和DL。

    AX的低8位(0位~7位)构成了AL寄存器,高8位(8位~15位)构成了AH寄存器,它们都是可以独立使用的8位寄存器。一个8位寄存器所能存储的数据的最大值是28-1。

    b.汇编指令

    汇编指令不区分大小写(和mysql一样大小写不敏感)

    丢失(不进位):丢失指的是进位制不能在 8 位寄存器中保存,但是 CPU 不是并真的不丢弃 这个进位值,这个问题以后再说。

     

     2、物理地址

    CPU访问内存单元时要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间。
    每一个内存单元在这个线性空间中都有唯一的地址,这个唯一的地址称为物理地址

    16位CPU的特征:

    • 运算器一次最多可以处理16位的数据。
    • 寄存器的最大宽度为16位。
    • 寄存器和运算器之间的通路是16位的

    因为8086CPU是16位的,所以它采用了一个机智的方法(地址加法器):在内部用两个16位地址合成的方法来形成一个20位的物理地址。

    小Tips:更多猛击这里

    CPU最大能查找多大范围的地址叫做寻址能力 ,CPU的寻址能力以字节为单位 ,如32位寻址
    的CPU可以寻址2的32次方大小的地址也就是4G,这也是为什么32位的CPU最大能搭配4G内
    存的原因 ,再多的话CPU就找不到了。
    
    16位寄存器,用二进制表示最小的数是0000000000000000,最大的数是1111111111111111。
    换算成十进制数就是0-65535,加上零就是65536(2^16)。
    也就是说一共可以存放65536个不同的地址。
    每一个地址在内存中占一个字节(Byte)。
    64KB = 65536byte,so 16位结构,表现出的寻址能力是64K。
    
    20位的寻址能力:2^20/1024/1024 = 1MB
    
    地址总线:属于一种电脑总线 (一部份),是CPU用来沟通某些单元想要存取(读取/写入)电脑内存元件/地方的实体位址。更多去看上一篇博客

    地址加法器合成物理地址的方法:物理地址=段地址×16+偏移地址

    一个16进制的数*16(向左移1位) ==> 一个二进制(向左移4位)

    举例说明物理地址=段地址×16+偏移地址

    8086CPU就是这样一个只能提供两张3位数据纸条的CPU。
    比如我们只能通过纸条来通信,读者问我图书馆的地址,我只能将它写在纸上告诉读者。
    显然我必须有一张可以容纳 4 位数据的纸条才能写下2826这个数据:

    不巧的是,没有能容纳4位数据的纸条,仅有两张可以容纳3位数据的纸条。
    这样我只能以这种方式告诉读者2826这个数据:

    给它两张纸条,让他把第一张纸条乘以10再加上第二张纸条的值就是我们要给它的物理地址(当然我们的是16进制的)

    • 段地址

      在编程时我们可以根据需要,将若干地址连续的内存单元看作一个段,用段地址×16定位段的起始地址(基础地址),用偏移地址定位相应段中的内存单元。

    小结:

    1、CPU访问内存单元时,必须向内存提供内存单元的物理地址
    8086CPU在内部用段地址和偏移地址移位相加的方法形成最终的物理地址

    (1)段地址×16 必然是 16的倍数,所以一个段的起始地址也一定是16的倍数;
    (2)偏移地址为16位,16 位地址的寻址能力为 64K,所以一个段的长度最大为64K。也就是说如果偏移地址都是最大64K,那么有16个段(因为20位的寻址能力为1MB)

    2、CPU可以用不同的段地址和偏移地址形成同一个物理地址。

    3、给定一个段地址,仅通过变化偏移地址来进行寻址,最多可以定位多少内存单元?
    结论:偏移地址16位,变化范围为0~FFFFH,仅用偏移地址来寻址最多可寻64K个内存单元。
    比如:给定段地址1000H,用偏移地址寻址,CPU的寻址范围为:10000H~1FFFFH。

    4、在8086PC机中,存储单元的地址用两个元素来描述。即段地址和偏移地址。

    “数据在21F60H内存单元中。”对于8086PC机的两种描述:
    (a)数据存在内存2000:1F60单元中;
    (b)数据存在内存的2000段中的1F60H单元中。
    可根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。

    答案

    1、給定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围是0010H到1000FH
    
    2、有一个数据存放在内存20000H单元中,现给定段地址为SA,若想用偏位地址寻到此单元,则SA应满足,最小为1001H,最大为2000H
    
    解:物理地址=段地址*16+偏移地址
        20000H=SA*16+偏移地址
        由于16为十进制,转换为十六进制=10H
        最小偏移地址=0H
        最大偏移地址=FFFFH
        最小SA=(20000H-FFFFH)/10H=20000H/10H-FFFFH/10H=2000H-FFFH=1001H
        最大SA=(20000H-0H)/10H=20000H/10H-0H/10H=2000H-0H=2000H
    
    3、当sa<1001H 或者sa>2000H  将无法寻到20000H单元
    

    3、段寄存器

    段寄存器就是提供段地址的
    8086CPU有4个段寄存器:

    •   CS(代码段)
    •   DS(数据段)
    •   SS(堆栈段)
    •   ES(附加段)

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

    CS和IP是8086CPU中最关键的寄存器,它们指示了CPU当前要读取指令的地址(其他的段+指针寄存器以后再说,)。

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

    8086PC的工作过程
    (1)从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
    (2)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指向过。

    修改CP和IP的指令:

    在CPU中,我们能够用指令读写的部件只有寄存器,我们可以通过改变寄存器中的内容实现对CPU的控制。
    CPU从何处执行指令是由CS、IP中的内容决定的,程序员可以通过改变CS、IP中的内容来控制CPU执行目标指令。

    那么问题来了,我们要怎样修改CS和IP的值呢?

    首先我们来思考一下,如何修改AX中的值?
    mov 指令
    如:mov ax,123
    mov指令可以改变8086CPU大部分寄存器的值,被称为传送指令。
    但mov指令不能改变CS、IP的值,CPU为我们提供了另外一个指令:jmp(转移指令)

    使用方法:

    # 同时修改CS和IP的值
    # 使用方法:jmp 段地址:偏移地址
    # 功能:用指令中给出的段地址修改CS,偏移地址修改IP。
    
    jmp 2AE3:3    # CS的地址-->3ae3 , 偏移地址 --> 0003
    
    jmp 3:0B16    # CS的地址-->0003 , 偏移地址 --> 0b16
    
    
    # 仅修改IP的内容:
    # jmp 某一合法寄存器
    # 功能:用寄存器中的值修改IP。
    
    jmp ax   (类似于 mov IP,ax)    # 修改IP的值为寄存器中的值
    
    jmp bx
    

    内存中存放的机器码和对应汇编指令情况: (初始:CS=2000H,IP=0000H),写出执行顺序。

    答案:

    (1)mov ax,6622
    (2)jmp 1000:3
    (3)mov ax,0000
    (4)mov bx,ax
    (5)jmp bx
    (6)mov ax,0123H
    (7)转到第(3)步执行
    

    小结:

    1、段地址在8086CPU的寄存器中存放。当8086CPU要访问内存时,由段寄存器提供内存单元的段地址。8086CPU有4个段寄存器,其中CS用来存放指令的段地址
    2、CS存放指令的段地址,IP存放指令的偏移地址
    8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
    3、8086CPU的工作过程:

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

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

    答案:

    下面3条指令执行后,CPU几次修改IP?都是在什么时候?最后IP中的值是多少?
    mov ax,bx sub ax,ax jmp ax 首先根据 代码 我们可以看到 mov ax,bx 我们将bx的值存入ax中,暂且不管bx的值为多少我们就认为bx中有一个数据 sub ax,ax 然后我们重新给ax赋值 ax = ax - ax ,所有ax的值应该为 0 jmp ax 当jmp指令,指向的是一个通用寄存器ax,代表的意思为修改 IP 的值 IP的值为ax 即 IP 的值应为0 所以CPU只修改了1次IP 执行到 jmp ax 时 修改了 IP中的值 为 0

      

  • 相关阅读:
    【转】如何解决Verilog中参数化的赋值:赋全0,赋全1,赋全Z,赋全x
    【转】PCIe DMA
    【转】PCIe学习(二)——PCIe DMA关键模块分析之一
    PCIe配置空间
    [转]PCIe学习笔记之MSI/MSI-x中断及代码分析
    [转]常用通信接口保护电路
    [转]原理图和PCB元件对应查找--Altium Designer
    [原]PCB中MARK点制作
    [转]使用Altium Designer软件铺铜后再挖铜
    支持Json进行操作的Javascript类库TAFFY DB
  • 原文地址:https://www.cnblogs.com/x54256/p/8067790.html
Copyright © 2020-2023  润新知