zoukankan      html  css  js  c++  java
  • 寄存器详解

    一般寄存器:AX、BX、CX、DX
    AX:累积暂存器,BX:基底暂存器,CX:计数暂存器,DX:资料暂存器

    索引暂存器:SI、DI
    SI:来源索引暂存器,DI:目的索引暂存器

    堆叠、基底暂存器:SP、BP
    SP:堆叠指标暂存器,BP:基底指标暂存器

    EAX、ECX、EDX、EBX:为ax,bx,cx,dx的延伸,各为32位元
    ESI、EDI、ESP、EBP:为si,di,sp,bp的延伸,32位元

    eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。

    比方说:add eax,-2 ; //可以认为是给变量eax加上-2这样的一个值。

    这些32位寄存器有多种用途,但每一个都有“专长”,有各自的特别之处。

    EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。

    EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址。

    ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。

    EDX 则总是被用来放整数除法产生的余数。

    ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.

    EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:
      
      push ebp ;保存当前ebp
      mov ebp,esp ;EBP设为当前堆栈指针
      sub esp, xxx ;预留xxx字节给函数临时变量.
      ...
      
      这样一来,EBP 构成了该函数的一个框架, 在EBP上方分别是原来的EBP, 返回地址和参数. EBP下方则是临时变量. 函数返回时作 mov esp,ebp/pop ebp/ret 即可.

    ESP 专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。在32位平台上,ESP每次减少4字节。

    esp:寄存器存放当前线程的栈顶指针
    ebp:寄存器存放当前线程的栈底指针

    eip:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。

    附加:

    首先介绍我们会经常看到的一些寄存器:
    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位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。

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

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

     

    根据上述的定义,在通常情况下ESP是可变的,随着栈的生产而逐渐变小,而ESB寄存器是固定的,只有当函数的调用后,发生入栈操作而改变。

    在上述的定义中使用ESP来标记栈的底部,他随着栈的变化而变化

    pop ebp;出栈 栈扩大4byte 因为ebp为32位

    push ebp;入栈,栈减少4byte

    add esp, 0Ch;表示栈减小12byte

    sub esp, 0Ch;表示栈扩大12byte

    而ebp寄存器的出现则是为了另一个目标,通过固定的地址与偏移量来寻找在栈参数与变量。而这个固定值者存放在ebp寄存器中,。但是这个值会在函数的调用过程发生改变。而在函数执行结束之后需要还原,因此,在函数的出栈入栈过程中进行保存。

    在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等。在win32的环境下EBP寄存器用与 存放在进入call以后的ESP的值,便于退出的时候回复ESP的值,达到堆栈平衡的目的。

    应用以前说过的一段话:

    原程序的OEP,通常是一开始以 Push EBP 和MOV Ebp,Esp这两句开始的,不用我多说大家也知道这两句的意思是以EBP代替ESP,作为访问堆栈的指针。

    为什么要这样呢?为什么几乎每个程序都是的开头能?因为如果我们写过C等函数的时候就应该清楚,程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的:

    1.让EBP保存ESP的值;

    2.在结束的时候调用

    mov esp,ebp 
    pop ebp 
    retn

    或者是

    leave
    retn


    两个形式是一个意思。

    这样做的好处是不用考虑ESP等于多少,PUSH了多少次,要POP多少次了,因为我们知道EBP里面放的是开始时候的ESP值。

  • 相关阅读:
    Linux常用命令-centos
    USACO 2006 Open, Problem. The Country Fair 动态规划
    USACO 2007 March Contest, Silver Problem 1. Cow Traffic
    USACO 2007 December Contest, Silver Problem 2. Building Roads Kruskal最小生成树算法
    USACO 2015 February Contest, Silver Problem 3. Superbull Prim最小生成树算法
    LG-P2804 神秘数字/LG-P1196 火柴排队 归并排序, 逆序对
    数据结构 并查集
    浴谷国庆集训 对拍
    1999 NOIP 回文数
    2010 NOIP 普及组 第3题 导弹拦截
  • 原文地址:https://www.cnblogs.com/wwkk/p/10629114.html
Copyright © 2011-2022 走看看