Assembly 汇编调用堆栈.术语问题

Assembly 汇编调用堆栈.术语问题,assembly,x86,stack,eip,Assembly,X86,Stack,Eip,我对Assembly是一个全新的人,希望在下面的陈述中确认我的误解,需要纠正 堆栈指针(ESP)指堆栈的顶部(最低内存地址) 基本指针(EBP)用于在构建堆栈帧时临时存储各种内存地址。它通常保存当前堆栈帧的最高内存地址 指令指针(EIP)指内存文本(代码)段中代码行的内存地址 一旦某些内容被推到堆栈中,就无法在适当的位置对其进行更改。也就是说,如果我们将EBP推到堆栈中,那么我们推的是EBP的当前值,而不是指向它的某种引用或指针。我们无法在适当的位置更改该值 传递到函数中的参数通常会移动到地址空

我对Assembly是一个全新的人,希望在下面的陈述中确认我的误解,需要纠正

堆栈指针(
ESP
)指堆栈的顶部(最低内存地址)

基本指针(
EBP
)用于在构建堆栈帧时临时存储各种内存地址。它通常保存当前堆栈帧的最高内存地址

指令指针
EIP
)指内存文本(代码)段中代码行的内存地址

一旦某些内容被推到堆栈中,就无法在适当的位置对其进行更改。也就是说,如果我们
将EBP
推到堆栈中,那么我们推的是
EBP
的当前值,而不是指向它的某种引用或指针。我们无法在适当的位置更改该值

传递到函数中的参数通常会移动到地址空间中,地址空间是堆栈指针的偏移量。例如,
[ESP-12]

调用函数时(使用
调用
),会发生以下情况:

  • 返回地址被添加到堆栈中(当前
    EIP
    之后的地址内存),因此我们知道在调用的函数完成后返回到哪里
  • 保存的帧指针添加到堆栈中,通常是调用函数的堆栈帧的堆栈指针
  • 然后我们将进入被调用函数的序言
  • 谢谢,我正想弄清楚这件事

    传递到函数中的参数通常会移动到地址空间中,地址空间是堆栈指针的偏移量。即[ESP-12]

    通常在调用之前,将参数推送到堆栈上

    push paramA  ; ( some 32bit value, register, whatever )
    push paramB
    call myFunct
    
    这将导致以下堆栈内容:

    ---------------
    |    paramA   |
    ---------------
    |    paramB   |
    ---------------
    | return addr |   <-- ESP
    --------------- 
    
    现在,堆栈如下所示:

    ---------------
    |    paramA   |
    ---------------
    |    paramB   |
    ---------------
    | return addr |   
    ---------------     
    |   saved EBP |   <-- EBP, ESP
    --------------- 
    
    局部变量位于
    [EBP-4]
    [EBP-8]
    [EBP-12]
    等处。
    回信地址位于
    [EBP+4]

    注意:如您所见,这是可能的

    • 要通过
      ESP
      访问,则不需要帧指针,但需要跟踪推送的数据量,以“查找”参数和变量)
    • 或者通过
      EBP
      (ofc会增加一些开销)。在许多函数中,帧指针根本不需要,并且由编译器进行优化
    一旦将某个内容推送到堆栈中,它就无法在适当的位置进行更改。即,如果我们将EBP推到堆栈中,则我们推的是EBP的当前值,而不是指向它的某种引用或指针。我们无法在适当的位置更改该值。

    当然可以。堆栈是普通的计算机内存,它没有什么特别之处,只是99%的代码需要
    esp
    中的有效(读写访问)内存地址和一些保留空间,所以它可以根据需要将一些本地内容推送到堆栈中

    push  ebp    ; store current value in ebp to stack
    
    几乎相当于:

    sub   esp,4
    mov   [esp],ebp
    
    (但第二个变体也会修改标志,而且原子性稍低)

    现在,您可以用任何其他内容覆盖它,例如:

    mov [esp],eax ; overwrite the old_ebp value with current_eax value
    
    引用或指向它的指针

    好的,没有办法有某种引用或指针指向
    ebp
    寄存器,它是CPU中的一个寄存器,只有32位(32x0或1个值),并且没有地址,您只能在指令中使用它的名称
    ebp
    ,这允许在编码中使用它


    按下ebp键后,这32位(没有其他信息)将被复制到内存中(内存将保存在自己的32位=4字节中复制的0/1值)。没有信息表明内存中的值是从何处写入的,何时写入的,由什么指令写入的,只存储值位。

    堆栈向下扩展,参数正偏移到
    esp
    ebp
    @Jester是的,愚蠢的我,已经注意到了(并修复了)。今天很辛苦:DYou也把偏移量弄错了:“函数的参数分别为[ESP+8]和[ESP+12]”应该分别为+4和+8。在没有帧指针的版本中,这就足够了。thx againIs值得一提(我知道问题中实际上没有要求它)关于如何避免使用EBP,只要使用当前的堆栈使用,就可以在整个函数中知道。(通常可用C或C++编译器优化)。
    sub   esp,4
    mov   [esp],ebp
    
    mov [esp],eax ; overwrite the old_ebp value with current_eax value