使用内联 ASM 调用函数

标签 c assembly inline-assembly

有没有办法使用内联汇编来调用MessageBox

#include<windows.h>
#pragma comment(lib,"user32.lib");

int main()
{
    MessageBox(0,"Hello","Title",1);
    return 0;
}

编辑:您提供的链接很好,但“ sleep ”只有一个参数。我需要一种方法将多个参数传递给我需要调用的函数。比如 MessageBox 函数。

最佳答案

我认为关于这个问题的评论非常清楚实际调用是如何进行的,现在让我们看看参数是如何传递的。

这是一个关于 Microsoft ABI 的直接问题。如下——

前 4 个参数在寄存器 %rcx、%rdx、%r8、%r9 中传递,其余在堆栈中传递。 所以剩下的可以压入堆栈,第 5 个在上面,第 6 个在下面。

现在有一个特性你必须要小心。您还必须在堆栈上为前 4 个参数留出空间。这意味着在调用之后,第 5 个参数将在 5 个(8 字节)槽之后(1 个用于返回地址和 4 个参数)。 您可以通过在推送第 5 个参数后执行 subq $32, %rsp 来实现。

这个额外的空间留给被调用者交换寄存器以备不时之需。

所以对于你的情况,

movq $0, %rcx

movq $hello, %rdx

movq $title, %r8

movq $1, %r9

调用消息框

PS:这个例子是在保持 64 位架构和 AT&T 语法的情况下编写的。 此外,*NIX 环境的 ABI 也不相同。 希望这会有所帮助。

编辑:事实上,在使用快速调用约定调用函数之前,最好始终在堆栈上留出空间,因为它们可能会交换寄存器,而您不希望堆栈帧被覆盖。

关于使用内联 ASM 调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42488273/

相关文章:

c++ - 为什么我在检查核心转储时进入 gdb "Cannot access memory at address 0x..."?

c - 0..9 约束在 GCC 内联汇编中有什么作用?

c - c 对角线差

c - 运行时错误 - c 中的指针

assembly - xor 之后的 x86 jnz?

c++ - 使用 Visual C++ 构建时如何使用 SSE(以及 SSE2、SSE3 等)扩展?

Linux 内核汇编和逻辑

使用 malloc 替换字符串中的子字符串的 C 函数——无字符串函数

c - 在 C 中使用无符号数据类型

optimization - 汇编中高数的划分