函数之间的参数的传输如何在组装中起作用?

发布于 2025-02-02 22:46:40 字数 1648 浏览 2 评论 0原文

因此,我试图了解组装编程如何与堆栈框架一起工作。
我进行了一些练习,并用GDB分解了一些C代码。现在的任务是找出“主”和函数之间参数的传输是如何工作的。我刚刚开始学习,有点迷失了下一个示例实际上要做的事情。关于从哪里开始的任何想法或提示?

这是与教师合作的递归计划。

装配代码看起来像这样:

    1149:   f3 0f 1e fa             endbr64 
    114d:   55                      push   rbp
    114e:   48 89 e5                mov    rbp,rsp
    1151:   48 83 ec 10             sub    rsp,0x10
    1155:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
    1158:   83 7d fc 01             cmp    DWORD PTR [rbp-0x4],0x1
    115c:   76 13                   jbe    1171 <f+0x28>
    115e:   8b 45 fc                mov    eax,DWORD PTR [rbp-0x4]
    1161:   83 e8 01                sub    eax,0x1
    1164:   89 c7                   mov    edi,eax
    1166:   e8 de ff ff ff          call   1149 <f>
    116b:   0f af 45 fc             imul   eax,DWORD PTR [rbp-0x4]
    116f:   eb 05                   jmp    1176 <f+0x2d>
    1171:   b8 01 00 00 00          mov    eax,0x1
    1176:   c9                      leave
    1177:   c3                      ret
    1178:   f3 0f 1e fa             endbr64
    117c:   55                      push   rbp
    117d:   48 89 e5                mov    rbp,rsp
    1180:   48 83 ec 10             sub    rsp,0x10
    1184:   c7 45 f8 05 00 00 00    mov    DWORD PTR [rbp-0x8],0x5
    118b:   c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
    1192:   8b 45 f8                mov    eax,DWORD PTR [rbp-0x8]
    1195:   89 c7                   mov    edi,eax
    1197:   e8 ad ff ff ff          call   1149 <f>
    119c:   89 45 fc                mov    DWORD PTR [rbp-0x4],eax

So I'm trying to understand how assembly programming works with stack frames etc.
I did some exercises and disassembled some C-code with GDB. The task now is to find out how the transfer of parameters between the 'main' and functions works. I just started learning and kinda got lost on what next example is actually doing. Any ideas or tips on where to get started?

It's a recursive program working with faculty.

The assembly code looks like this:

    1149:   f3 0f 1e fa             endbr64 
    114d:   55                      push   rbp
    114e:   48 89 e5                mov    rbp,rsp
    1151:   48 83 ec 10             sub    rsp,0x10
    1155:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
    1158:   83 7d fc 01             cmp    DWORD PTR [rbp-0x4],0x1
    115c:   76 13                   jbe    1171 <f+0x28>
    115e:   8b 45 fc                mov    eax,DWORD PTR [rbp-0x4]
    1161:   83 e8 01                sub    eax,0x1
    1164:   89 c7                   mov    edi,eax
    1166:   e8 de ff ff ff          call   1149 <f>
    116b:   0f af 45 fc             imul   eax,DWORD PTR [rbp-0x4]
    116f:   eb 05                   jmp    1176 <f+0x2d>
    1171:   b8 01 00 00 00          mov    eax,0x1
    1176:   c9                      leave
    1177:   c3                      ret
    1178:   f3 0f 1e fa             endbr64
    117c:   55                      push   rbp
    117d:   48 89 e5                mov    rbp,rsp
    1180:   48 83 ec 10             sub    rsp,0x10
    1184:   c7 45 f8 05 00 00 00    mov    DWORD PTR [rbp-0x8],0x5
    118b:   c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
    1192:   8b 45 f8                mov    eax,DWORD PTR [rbp-0x8]
    1195:   89 c7                   mov    edi,eax
    1197:   e8 ad ff ff ff          call   1149 <f>
    119c:   89 45 fc                mov    DWORD PTR [rbp-0x4],eax

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

帅冕 2025-02-09 22:46:40

研究环境的呼叫大会。&nbsp;许多架构的概述概述:

  1. ​;对于要通过的参数,单点是在调用后和Callee的第一个指令之前(对于返回值,在Callee完成的点以及在呼叫者中恢复执行之前)。

    许多约定将传递CPU寄存器中的参数与堆栈内存中的参数结合在一起,用于不适合CPU寄存器的参数。&nbsp;甚至有些不使用CPU寄存器进行参数的人仍然使用CPU寄存器进行返回值。

  2. 允许哪些登记函数才能抓住vs.必须保留。&nbsp;可以在不关注的情况下分配呼叫关闭的寄存器。&nbsp;可以使用呼叫保存的寄存器,但必须将其恢复到返回呼叫者之前进入时的价值。&nbsp;呼叫保存的寄存器的优点是,由于它们是由呼叫保存的,因此您可以将它们用于需要在另一个呼叫中生存的变量。

  3. 含义&amp;堆栈指针的处理,有关当前指针下方和更高的内存以及堆栈分配的对齐要求。

如果该函数以某种方式分配堆栈空间,则似乎将似乎似乎会移动远离堆栈顶部(当然,它们实际上并没有移动,但是从当前的堆栈或框架指针中变得更大)。&NBSP。 ;编译器知道这一点,并相应地调整他们对堆栈内存的访问。

一些编译器设置了框架指针,以参考堆栈内存。&nbsp;框架指针是序言中某个时候制作的堆栈指针的副本。&nbsp;框架指针并不总是必要的,而是促进异常处理和堆栈放松,以及动态的堆栈分配。

Study the calling convention for your environment.  An overview of the many calling conventions for a number of architectures: https://www.dyncall.org/docs/manual/manualse11.html

The calling convention specifies:

  1. Where parameters and return values must appear at the one single point of transfer of control of the instruction stream from the caller to the callee.  For parameters being passed, that single point is after the call is made and before the first instruction of the callee (and for return values, at the point where the callee finishes and just before execution resumes in the caller).

    Many conventions combine parameter passing in CPU registers with stack memory for parameters that don't fit in CPU registers.  And even some that don't use CPU registers for parameters still use CPU registers for return values.

  2. What registers a function is allowed to clobber vs. must preserve.  Call-clobbered registers can be assigned new values without concern.  Call-preserved registers can be used but must be restored to the value they had upon entry before returning to the caller.  The advantage of call-preserved registers is that since they are preserved by a call, you can use them for variables that need to survive another call.

  3. The meaning & treatment of the stack pointer, regarding memory below and above the current pointer, and alignment requirements for stack allocation.

If the function allocates stack space in some manner, then memory parameters will appear to move farther away from the top of the stack (they don't actually move, of course, but become larger offsets from the current stack or frame pointer).  Compilers know this and adjust their access to stack memory accordingly.

Some compilers set up frame pointers to refer to stack memory.  A frame pointer is a copy of the stack pointer made at some point in the prologue.  Frame pointers are not always necessary but facilitate exception handling and stack unwinding, as well as dynamic stack allocation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文