繁体   English   中英

如何在Windows函数调用中设置堆栈?

[英]How is the stack set up in a Windows function call?

首先,我想说我在汇编方面有足够的背景知识,以理解成为一名功能性汇编程序员所需要了解的大部分知识。 不幸的是,我不了解Windows API调用在返回地址方面的工作方式。

这是一些使用Windows的GAS汇编语言编写的示例代码,使用MinGW作为汇编程序,MinGW ld作为链接程序...

    .extern _ExitProcess@4
    .text
    .globl _main
_main:
     pushl $0
     call _ExitProcess@4

该代码在组装后编译并运行...

as program.s -o program.o

并将其链接...

ld program.o -o program.exe -lkernel32

据我了解,Windows API调用通过推送指令接受参数,如上所示。 然后在通话中;

call _ExitProcess@4

该函数的返回地址放在堆栈中。 然后,这就是我感到困惑的地方,该函数将所有参数弹出堆栈。

我感到困惑是因为,由于堆栈是后进先出的,因此我在弹出堆栈中的参数时会先弹出返回地址。 首先是参数,然后是返回地址,因此从技术上讲应该先弹出。

我的问题是,在通过push操作将参数传递给函数调用并将返回地址放置在堆栈上之后,堆栈的布局是什么样的? 函数在执行时如何从堆栈中弹出参数和返回地址? 最后,返回地址如何从堆栈中弹出,函数调用返回到返回地址中指定的地址?

几乎所有Windows API函数都使用stdcall调用约定 就像正常的“ cdecl”约定一样,除了您看到调用的函数负责在返回参数时删除该参数之外,它的工作原理相同。 它使用RET指令执行此操作,该指令采用一个可选的立即操作数。 此操作数是第一次弹出返回值后要从堆栈弹出的字节数。

在cdecl和stdcall调用约定中,函数执行时不会将函数的参数弹出堆栈。 它们留在堆栈上,并使用ESP或EBP相对寻址进行访问。 因此,当ExitProcess需要访问其参数时,它使用诸如mov 4(%esp), %eaxmov 4(%ebp), %eax类的指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM