精华内容
下载资源
问答
  • 寄存器

    2021-04-22 11:47:59
    首先介绍我们会经常看到的一些寄存器: 4个数据寄存器(EAX、EBX、ECX和EDX) 2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 4个数据寄存器(EAX、EBX、ECX和EDX): 32位CPU有4个32位的通用寄存器EAX、EBX、...

    首先介绍我们会经常看到的一些寄存器:
    4个数据寄存器(EAX、EBX、ECX和EDX)
    2个变址和指针寄存器(ESI和EDI)
    2个指针寄存器(ESP和EBP)


    4个数据寄存器(EAX、EBX、ECX和EDX):
    32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取,不会影响高16位的数据。这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。
    4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。程序员可利用数据寄存器的这种“可分可合”的特性,灵活地处理字/字节的信息。

    那么如何理解eax,ax,al(ah)之间的关系呢?
    专业点可以这样解释:Eax是32位寄存器,ax是16位寄存器,al(ah)是八位寄存器。
    那么eax存储的数据就是ax的两倍,ax是al(ah)的两倍。
    Eax可以存储的数字是DWORD(双字)ax存储的是WORD(字)AL(AH)存储的是BYTE(字节),那么为什么又有AH和AL呢,我们可以这样理解,AX=AH+AL,AH存储的是AX的高8位数据,AL存储的是AX的低八位数据。H这里就是HIGH,L就是LOW.
    假设eax是红色区域,那么eax现在就是64636261;
    那么ax就是eax的低十六位,也就是6261;
    Al是61;AH是62。



    其他ebx,ecx,edx也有类似的bx,bl,bh等对应的寄存器,原理和上面相同。

    在用途方面,他们有各自默认的用途:
    Eax用来保存所有API函数的返回值。
    寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、除、输入/输出等操作,它们的使用频率很高;
    寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用; 
    寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数;
    寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。

    由于存储的数据大小关系,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址, 32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。(什么是基址,什么是变址以后会说到)

    2个变址和指针寄存器(ESI和EDI)
    32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。

    寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
    变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。

    2个重要的指针寄存器(ESP和EBP)


    这两个指针寄存器都和“栈”这个神秘的东东有关,那么什么是栈呢?这俩指针寄存器又有何作用呢?


    从计算机科学的角度看,栈是一种数据结构,是一种先进后出的数据表。栈的最常见操作有两种:Push(入栈)和Pop(出栈)。


    我们可以把栈想象成一摞扑克牌:
    PUSH:为栈增加一个元素的操作是push,相当于在这摞扑克牌最上面再放一张

    POP:从栈中取出一个元素的操作叫做POP,相当于从这摞扑克牌取出最上面的一

    张。

    TOP:标识栈顶位置,并且是动态变化的。每做一次PUSH 操作,它都会自增1;

    相反,每做一次POP 操作,它会自减1。栈顶元素相当于扑克牌最上面一张,只有


    这张牌的花色是当前可以看到的。

    BASE:标识栈底位置,它记录着扑克牌最下面一张的位置。BASE 用于防止栈空后

    继续弹栈(牌发完时就不能再去揭牌了)。很明显,一般情况下,BASE 是不会变动


    的。
     

    用王爽《汇编语言》中的图说明一下push和pop操作
    代码如下:
    mov ax,0123H
    push ax
    mov bx,2266H
    push bx
    mov cx,1122H
    pop ax
    pop bx
    pop cx

    mov是传送数据的指令,mov ax,0123H表明把0123H这个值给ax
    H代表0123是十六进制数

     



    mov是传送数据的指令,mov ax,0123H表明把0123H这个值给ax
    H代表0123是十六进制数
    图中左边的10000H等数值表明内存地址
    箭头指向栈顶位置

     

    那么针对此例栈底就是1000FH
    栈顶由于入栈和出栈操作在不断变化。

    那么在这里栈底1000FH就是BP 栈顶(不断变化的箭头)就是SP
    (BP和SP分别是16位下的寄存器,与ebp,esp类似)

    内存的栈区实际上指的就是系统栈。系统栈由系统自动维护,它用于实现高级语言中函

    数的调用。对于类似C 语言这样的高级语言,我们无需担心他们是如何操作的。一般说来,只有在使用汇编语言的时候,才需要和它直接打交道。

    那么ESP和EBP指的分别是什么呢?

    (1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
    (2)EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

    展开全文
  • 地址空间是一个进程可用于寻址内存的一套地址集合。每个进程都有一个自己的地址空间,并且这...方法:基址寄存器与界限寄存器使用一种简单的动态重定位,把每个进程的地址空间映射到物理内存的不同部分。当使用基址...

    地址空间是一个进程可用于寻址内存的一套地址集合。每个进程都有一个自己的地址空间,并且这个地址空间独立于其他进程的地址空间(除了在一些特殊情况下进程需要共享它们的地址空间外)。

    给每个程序一个自己的地址空间,使得一个程序中的地址28所对应的物理地址与另一个程序中的地址28所对应的物理地址不同。方法:

    基址寄存器与界限寄存器

    使用一种简单的动态重定位,把每个进程的地址空间映射到物理内存的不同部分。当使用基址寄存器和界限寄存器时,程序装载到内存中连续的空闲位置且装载期间无须重定位,如图3-2c所示。当一个进程运行时,程序的起始物理地址装载到基址寄存器中,程序的长度装载到界限寄存器中。在图3-2c中,当第一个程序运行时,装载到这些硬件寄存器中的基址和界限值分别是0和16 384。当第二个程序运行时,这些值分别是16 384和16384。如果第三个16KB的程序被直接装载在第二个程序的地址之上并且运行,这时基址寄存器和界限寄存器里的值会是32 768和16 384。

    每次一个进程访问内存,取一条指令,读或写一个数据字,CPU硬件会在把地址发送到内存总线前,自动把基址值加到进程发出的地址值上。同时,它检查程序提供的地址是否等于或大于界限寄存器里的值。如果访问的地址超过了界限,会产生错误并中止访问。这样,对图3-2c中第二个程序的第一条指令,程序执行

    1. JMP 28 

    指令,但是硬件把这条指令解释成为(28+16384=16412)

    1. JMP 16412 

    所以程序如我们所愿地跳转到了CMP指令。在图3-2c中第二个程序的执行过程中,基址寄存器和界限寄存器的设置如图3-3所示。

      

    图3-2   重定位问题的说明:a) 一个16KB程序;b) 另一个16KB程序;c) 两个程序连续地装载到内存中

     

    使用基址寄存器和界限寄存器是给每个进程提供私有地址空间的非常容易的方法,因为每个内存地址在送到内存之前,都会自动先加上基址寄存器的内容。在很多实际系统中,对基址寄存器和界限寄存器会以一定的方式加以保护,使得只有操作系统可以修改它们。

    使用基址寄存器和界限寄存器重定位的缺点是,每次访问内存都需要进行加法和比较运算。比较可以做得很快,但是加法由于进位传递时间的问题,在没有使用特殊电路的情况下会显得很慢。



    展开全文
  • 本文提出了一种动态寄存器分配器,该分配器可动态检测并利用群集VLIW处理器的生存期漏洞。生存期漏洞是一个变量不包含有效值的时间间隔。可以将保存生存期漏洞的寄存器分配给有效范围适合生存期漏洞的另一个变量,...
  • 地址空间是一个进程可用于...使用一种简单的动态重定位,把每个进程的地址空间映射到物理内存的不同部分。当使用基址寄存器和界限寄存器时,程序装载到内存中连续的空闲位置且装载期间无须重定位,如图3-2c所示。当一.

    地址空间是一个进程可用于寻址内存的一套地址集合。每个进程都有一个自己的地址空间,并且这个地址空间独立于其他进程的地址空间(除了在一些特殊情况下进程需要共享它们的地址空间外)。

    给每个程序一个自己的地址空间,使得一个程序中的地址28所对应的物理地址与另一个程序中的地址28所对应的物理地址不同。方法:

    基址寄存器与界限寄存器

    使用一种简单的动态重定位,把每个进程的地址空间映射到物理内存的不同部分。当使用基址寄存器和界限寄存器时,程序装载到内存中连续的空闲位置且装载期间无须重定位,如图3-2c所示。当一个进程运行时,程序的起始物理地址装载到基址寄存器中,程序的长度装载到界限寄存器中。在图3-2c中,当第一个程序运行时,装载到这些硬件寄存器中的基址和界限值分别是0和16 384。当第二个程序运行时,这些值分别是16 384和16384。如果第三个16KB的程序被直接装载在第二个程序的地址之上并且运行,这时基址寄存器和界限寄存器里的值会是32 768和16 384。

    每次一个进程访问内存,取一条指令,读或写一个数据字,CPU硬件会在把地址发送到内存总线前,自动把基址值加到进程发出的地址值上。同时,它检查程序提供的地址是否等于或大于界限寄存器里的值。如果访问的地址超过了界限,会产生错误并中止访问。这样,对图3-2c中第二个程序的第一条指令,程序执行

    1. JMP 28 

    指令,但是硬件把这条指令解释成为(28+16384=16412)

    1. JMP 16412 

    所以程序如我们所愿地跳转到了CMP指令。在图3-2c中第二个程序的执行过程中,基址寄存器和界限寄存器的设置如图3-3所示。

     

      

     

    图3-2   重定位问题的说明:a) 一个16KB程序;b) 另一个16KB程序;c) 两个程序连续地装载到内存中

     

    使用基址寄存器和界限寄存器是给每个进程提供私有地址空间的非常容易的方法,因为每个内存地址在送到内存之前,都会自动先加上基址寄存器的内容。在很多实际系统中,对基址寄存器和界限寄存器会以一定的方式加以保护,使得只有操作系统可以修改它们。

    使用基址寄存器和界限寄存器重定位的缺点是,每次访问内存都需要进行加法和比较运算。比较可以做得很快,但是加法由于进位传递时间的问题,在没有使用特殊电路的情况下会显得很慢。

     

    程序执行时,必须将地址空间变为绝对地址才能访问系统分配的内存

    地址重定位:操作系统把用户程序指令中的相对地址变换成为所在存储中的绝对地址的过程

    地址重定位实现了:从逻辑地址到物理地址的转换

     

    地址的静态重定位

    定义:在程序运行之前,为用户程序实行了地址重定位工作

    一般由操作系统中的重定位装入程序完成

    重定位装入程序的输入:用户把自己的作业链接装配成一个相对于 0 编址的目标程序

    实现过程:

    静态重定位的处理方法为在加载程序到内存中时,将程序中所有的地址都加上在内存中的起始地址。比如一个程序被加载到从1000号开始的内存空间,而且程序中有一条指令JMP 28,那么程序被加载入内存后这条指令会变成 JMP 1028。静态重定位的难点在于区分程序中哪些值是常量,哪些值是地址。

    特点:

    • 在装入前实现调整
    • 地址要有标识
    • 每次装入都要进行定位
    • 装入后地址不再改变(静态)

    地址的动态重定位

    定义:在程序执行寻址时进行重定位,访问地址时,通过地址变换机构改变为内存地址,用户程序原封不动的装入内存,运行时再完成地址的定位工作。动态重定位需要硬件的支持,要求系统中配备定位寄存器和加法器。

    实现过程:

    使用动态重定位的cpu有两个特殊的寄存器:基址寄存器和界限寄存器。当一个进程运行时,程序的起始地址被装载到基址寄存器中,程序的长度被装载到界限寄存器中。当程序要进行内存操作时,cpu会首先将指令中的地址加上基址寄存器中的地址,再把地址送到内存总线。此外,cpu还会检查地址是否大于界限寄存器中的值。如果访问的地址超出了界限则会出错并停止访问。

    特点:

    • 程序可装入任意内存区域(不要求占用连续的内存区)
    • 只装入部分程序代码即可运行
    • 改变系统时不需要改变程序(程序占用的内存空间动态可变,只需要改变定位寄存器中的值即可)
    • 程序可方便共享

     


     

    展开全文
  • 动态映射之结构体方式操作寄存器 仿效真实驱动中,用结构体封装的方式来进行单次多个寄存器的地址映射。即代替文章《随笔–Linux字符设备驱动开发基础》中动态映射操作LED一节的基础动态映射方式

    动态映射之结构体方式操作寄存器

    仿效真实驱动中,用结构体封装的方式来进行单次多个寄存器的地址映射。即代替文章《随笔–Linux字符设备驱动开发基础》中动态映射操作LED一节的基础动态映射方式

    #include <linux/io.h>
    #include <linux/ioport.h>
    ......
    typedef struct GPJ0REG
    {
        volatile unsigned int gpj0con;
        volatile unsigned int gpj0dat; 
    }gpj0_reg_t;
    
    //#define GPJ0CON_PA    0xe0200240
    //#define GPJ0DAT_PA    0xe0200244
    #define GPJ0_REGBASE    0xe0200240
    
    //unsigned int *pGPJ0CON;       //指针类型才能接受ioremap返回的地址
    //unsigned int *pGPJ0DAT;
    gpj0_reg_t *pGPJ0REG;     
    
    ...
    // 模块安装函数
    static int __init chrdev_init(void)
    {
            //注册字符设备驱动
        ...
    #if 0
        // 使用动态映射的方式来操作寄存器
        if (!request_mem_region(GPJ0CON_PA, 4, "GPJ0CON"))
            return -EINVAL;
        if (!request_mem_region(GPJ0DAT_PA, 4, "GPJ0DAT"))
            return -EINVAL;
        pGPJ0CON = ioremap(GPJ0CON_PA, 4);
        pGPJ0DAT = ioremap(GPJ0DAT_PA, 4);
    
        *pGPJ0CON = 0x11111111;
        *pGPJ0DAT = ((0<<3) | (0<<4) | (0<<5));    // 亮
    #endif
        // 2步完成映射
        if (!request_mem_region(GPJ0_REGBASE, sizeof(gpj0_reg_t), "GPJ0REG"))
            return -EINVAL;
        pGPJ0REG = ioremap(GPJ0_REGBASE, sizeof(gpj0_reg_t));
        // 映射之后用指向结构体的指针来进行操作
        // 指针使用->结构体内元素 的方式来操作各个寄存器
        pGPJ0REG->gpj0con = 0x11111111;
        pGPJ0REG->gpj0dat = ((0<<3) | (0<<4) | (0<<5));    // 亮
            ...
    }
    // 模块卸载函数
    static void __exit chrdev_exit(void)
    {
            ...
        // 解除映射
    #if 0
        iounmap(pGPJ0CON);
        iounmap(pGPJ0DAT);
        release_mem_region(GPJ0CON_PA, 4);
        release_mem_region(GPJ0DAT_PA, 4);
    #endif
        iounmap(pGPJ0REG);
        release_mem_region(GPJ0_REGBASE, sizeof(gpj0_reg_t));
            ...
            //注销字符设备驱动
            ...
    }

    动态映射结构体方式操作寄存器:在结构体中添加相应成员就可以,不用像之前的那么麻烦

    展开全文
  • 寄存器变量

    2019-10-12 23:19:48
    1.寄存器变量可以用来优化加速c语言程序 2.声名只需在类型前多加register 即可,eg register int quick; (quick 就是一个整形的寄存器变量) 3.register只是一个建议型关键字,能不能声名成功还取决于编译器(建议...
  • 选择寄存器

    2021-04-25 09:56:47
    2.(人口动态,户籍 ... "register select"中文翻译寄存器选择 "color select register"中文翻译彩色选择寄存器 "csr channel select register"中文翻译通道选择寄存器 "memory address select register"中文...
  • 捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。读写过程仅操作预装载寄存器。在捕获模式下,捕获发生在影子寄存器上,然后再复制到预装载寄存器中。在比较模式下,预装载寄存器的内容被复制到影子寄存器中...
  • 当我们调试驱动程序的时候,可能要调整寄存器的设置。按照我们之前的作法就是直接在程序里面修改,然后重新编译程序。...这样就可以动态调试寄存器设置了,不需要每次配置好了再重新烧写。
  • 寄存器编址

    千次阅读 2014-04-12 15:37:45
    外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。 CPU对外设IO端口物理地址的编址方式有两种:一种是I/O映射方式(I/O-mapped),另一...
  • CCRX寄存器

    万次阅读 2016-08-11 15:27:58
    TIMx_CCRx寄存器能够在任何时候通过软件进行更新以控制输出波形,条件是未使用预装载寄存器(OCxPE=’0’,否则TIMx_CCRx影子寄存器只能在发生下一次更新事件时被更新)。这里设置为Disable 就是为了后面在中断服务子...
  • MIPS通用寄存器

    2018-11-02 23:03:00
    MIPS通用寄存器 MIPS有32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下: 下表描述32个通用寄存器的别名和用途 REGISTER NAME USAGE $0 $zero 常量0(constant value 0) $1 $at ...
  • //向内核申请寄存器地址空间 if (!request_mem_region(0xE0200240, 4,"gpip_con")) return -EINVAL; //0xE020_0244 is the start of the gpj0 data register if (!request_mem_region(0xE0200244, 4,"gpip_data...
  • 移位寄存器

    2015-02-25 12:17:00
    寄存器是计算机和其它数字系统中用来存储代码或数据的逻辑部件。它的主要组成部分是触发器。一个触发器能存储1位二进制代码,所以要存储n位二进制代码的寄存器就须要用n个触发器组成。一个4位的集成寄存器74LS...
  • 经常有人问起预装寄存器和影子寄存器的话题,其实STM32相关系列的手册里有介绍,有文档做介绍,这里借花献佛地一起分享下。 在谈预装寄存器及影子寄存器的差别前,不妨先对STM32定时器的时基单元做个基本了解。STM...
  • register寄存器变量

    2018-03-19 14:05:57
    对register寄存器变量的总结如下: 1.寄存器变量可以用来优化加速c语言程序 2.声名只需在类型前多加register 即可,eg register int quick; (quick 就是一个整形的寄存器变量) 3.register只是一个建议型关键字...
  • 2、动态变量(又称自动变量),是在函数内部定义,需要时才分配内存,退出函数时自动释放的变量。自动变量存储空间的分配和回收是由系统自动完成的,所以也叫自动变量。一般情况下,不作专门说明的局部变量,均是...
  • LINUX寄存器总结

    2020-08-03 21:45:48
    前言(wxy):说到寄存器,迷迷茫茫好多年,首先不知道到底有哪些寄存器,因为不同的博客总会出现几个我不认识的寄存器;其次,想记住每个寄存器的名称,真的太南了;最后,他们到干什么用的,寄存器之间到底什么关系...
  • 概述x86寄存器

    2019-08-16 11:44:48
    x86寄存器 ·x86寄存器分类: 8个通用寄存器:EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP 1个标志寄存器:EFLAGS 6个段寄存器:CS、DS、ES、FS、GS、SS 5个控制寄存器:CR0、CR1、CR2、CR3、CR4 8个调试寄存器:...
  • x86寄存器总结

    2019-03-06 13:35:00
    X86寄存器 ·x86寄存器分类: 8个通用寄存器:EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP 1个标志寄存器:EFLAGS 6个段寄存器:CS、DS、ES、FS、GS、SS 5个控制寄存器:CR0、CR1、CR2、CR3、CR4 8个调试寄存器:...
  • register 寄存器变量

    2019-05-03 14:26:55
    1.寄存器变量可以用来优化加速c语言程序 2.声名只需在类型前多加register 当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 122,765
精华内容 49,106
关键字:

动态寄存器