程序集调用堆栈-术语问题 [英] Assembly Call Stack - Terminology Questions

查看:118
本文介绍了程序集调用堆栈-术语问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm completely new to Assembly and looking to confirm where, in the following statements, I have a misunderstanding and need to be corrected.

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

The stack pointer (ESP) refers to the top (lowest memory address) of the stack.

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

The base Pointer (EBP) is used for temporarily storing various memory addresses when building a stack frame. It normally holds the highest memory address of the current stack frame.

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

The instruction pointer (EIP) refers to the memory address of a line of code in the text (code) segment of memory

一旦某些东西被推入堆栈,就不能就地更改. IE.如果我们PUSH EBP到堆栈,我们将推送EBP的当前值,而不是某种引用或指针.然后,我们无法就地更改该值.

Once something has been pushed to the stack, it can't be changed in-place. ie. If we PUSH EBP to the stack, we are pushing the current value of EBP, not some kind of reference or pointer to it. We can't then change that value in-place.

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

Arguments being passed into a function are generally moved into an address space which is an offset of the stack pointer. ie. [ESP-12].

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

When a function is called (using CALL), the following occurs:

  1. 返回地址被添加到堆栈中(当前EIP之后紧随其后的地址的内存,因此我们知道在被调用函数完成之后要返回的位置
  2. 已保存的帧指针已添加到堆栈中,通常是调用函数的堆栈帧的堆栈指针
  3. 然后我们进入被调用函数的序幕
  1. The return address is added to the stack (the memory of the address immediately following the current EIP so we know where to return to after the called function has completed
  2. The saved frame pointer is added to the stack, which is normally the stack pointer of the stack frame of the calling function
  3. We would then move into the prologue of the called function

谢谢.我正在努力弄清楚这些东西.

Thanks. I'm trying to get my head around this stuff.

推荐答案

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

Arguments being passed into a function are generally moved into an address space which is an offset of the stack pointer. ie. [ESP-12].

通常在调用前 将参数压入堆栈.

Often arguments are pushed on the stack, before the call.

push paramA  ; ( some 32bit value, register, whatever )
push paramB
call myFunct

这将导致以下堆栈内容:

This leads to the following stack content:

---------------
|    paramA   |
---------------
|    paramB   |
---------------
| return addr |   <-- ESP
--------------- 

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

Since the return address (pushed by the call ) is 4 bytes, the parameters for the function are at [ESP+4] and [ESP+8].

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

If your function adds a stack frame, usually you do

myFunct:  push EBP
          mov EBP, ESP

现在堆栈看起来像这样:

Now the stack looks like this:

---------------
|    paramA   |
---------------
|    paramB   |
---------------
| return addr |   
---------------     
|   saved EBP |   <-- EBP, ESP
--------------- 

并且参数位于[EBP+8][EBP+12],即使您按EBP不再更改,即使您推入更多值(或为局部变量添加一些位置),也是如此:

and the parameters are at [EBP+8] and [EBP+12], even if you push more values (or add some place for local variables) since EBP is not changing anymore:

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)
           --------------- 

局部变量位于[EBP-4][EBP-8][EBP-12]等处.
返回地址在[EBP+4]

The local variables are at [EBP-4], [EBP-8], [EBP-12] etc.
The return Address is at [EBP+4]

注意:如您所见,有可能

Note: As you can see, it is possible

  • 通过ESP访问(然后,您不需要需要框架指针,但是您需要跟踪所推送的数据量,以查找"参数和变量)
  • EBP(这会增加一些开销).在许多函数中,根本不需要帧指针,并且已由编译器对其进行了优化.
  • to access by ESP (then you do not need a frame-pointer, but then you need to keep track of how much data you pushed, to "find" the parameters and variables )
  • or by EBP (which ofc adds some overhead). In many functions, the frame pointer is not needed at all, and optimized away by compilers.

这篇关于程序集调用堆栈-术语问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆