汇编调用堆栈 - 术语问题

Jor*_*dan 2 x86 assembly stack eip

我是全新的大会,并希望确认在以下陈述中我有哪些误解,需要纠正.

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

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

指令指针(EIP)指的是存储器的文本(代码)段中的一行代码的存储器地址

一旦某些东西被推入堆栈,它就不能就地更改.即.如果我们PUSH EBP到堆栈,我们正在推送当前值EBP,而不是某种引用或指针.然后我们不能就地改变这个价值.

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

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

  1. 返回地址被添加到堆栈(紧跟当前的地址的内存,EIP因此我们知道在被调用函数完成后返回的位置
  2. 保存的帧指针被添加到堆栈中,堆栈通常是调用函数的堆栈帧的堆栈指针
  3. 然后我们将进入被调用函数的序言

谢谢.我正试着绕过这些东西.

Tom*_*e2k 7

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

在调用之前,通常会在堆栈上推送参数.

push paramA  ; ( some 32bit value, register, whatever )
push paramB
call myFunct
Run Code Online (Sandbox Code Playgroud)

这导致以下堆栈内容:

---------------
|    paramA   |
---------------
|    paramB   |
---------------
| return addr |   <-- ESP
--------------- 
Run Code Online (Sandbox Code Playgroud)

由于返回地址(由其推call)是4个字节,因此该函数的参数为[ESP+4][ESP+8].

如果你的函数添加了一个堆栈框架,通常你会这样做

myFunct:  push EBP
          mov EBP, ESP
Run Code Online (Sandbox Code Playgroud)

现在堆栈看起来像这样:

---------------
|    paramA   |
---------------
|    paramB   |
---------------
| return addr |   
---------------     
|   saved EBP |   <-- EBP, ESP
--------------- 
Run Code Online (Sandbox Code Playgroud)

并且参数是[EBP+8][EBP+12],即使你推更多的值(或为局部变量添加一些位置),因为EBP不再改变:

myFunct:  push EBP
          mov EBP, ESP
          sub ESP, 12      ; make room for 3 32bit local variables

          mov eax, [EBP+8] ; access one of the parameters
          mov [EBP-4], eax ; save it in local variable #1

rel |  rel |
to  |  to  |
ESP |  EBP |
----|------|--------------
+24 | +12  |    paramA   |
    |      |--------------
+20 | +8   |    paramB   |
    |      |--------------
+16 | +4   | return addr |  
    |      |--------------
+12 |      |   saved EBP |  <-- EBP   (is fixed here for now)
    |      |--------------- 
+8  | -4   |    local#1  |
    |      |--------------- 
+4  | -8   |    local#2  |
    |      | --------------- 
0   | -12  |    local#3  |  <--- ESP  (keeps growing, by pushing, calling etc)
           --------------- 
Run Code Online (Sandbox Code Playgroud)

局部变量是在[EBP-4],[EBP-8],[EBP-12]
返回地址是[EBP+4]

注意:正如您所看到的,这是可能的

  • 通过访问ESP(那么你就不会需要一个帧指针,但你需要跟踪的多少数据推动,"发现"的参数和变量)
  • 或者EBP(通过增加一些开销).在许多函数中,根本不需要帧指针,并且由编译器优化掉.

  • 堆栈增长,参数为**正**偏移到'esp`和`ebp`. (2认同)