3

我正在Assembly中编写一个简单的基于图形的程序用于学习目的;为此,我打算使用 OpenGL 或 SDL。我正在尝试从程序集中调用 OpenGL/SDL 的函数。

问题是,与我在互联网上找到的许多汇编和 OpenGL/SDL 教程不同,我机器中的 OpenGL/SDL 显然不使用 C 调用约定。我用 C 编写了一个简单的程序,将其编译为汇编(使用 -S 开关),显然由 GCC 生成的汇编代码通过在寄存器中传递参数而不是被推送到堆栈来调用 OpenGL/SDL 函数。

现在,问题是,我如何确定如何将参数传递给这些 OpenGL/SDL 函数?也就是说,我如何确定哪个参数对应于哪个寄存器?

显然由于GCC可以编译C代码来调用OpenGL/SDL,所以必须有办法弄清楚函数参数和寄存器的对应关系。在 C 调用约定中,规则很简单,向后推参数并在 eax/rax 中返回值,我可以简单地阅读他们的 C 文档,我可以很容易地弄清楚如何传递参数。但是这些呢?

有没有办法使用 C 调用约定来调用 OpenGL/SDL?

顺便说一句,我使用的是 yasm,gcc/ld 作为 Gentoo Linux amd64 上的链接器。

4

3 回答 3

6

在 x86-64 linux 系统上,函数调用遵循标准的 x86-64 ABI 约定。简而言之:

  • 前六个整数/指针参数按 rdi、rsi、rdx、rcx、r8、r9 的顺序传递。
  • 前八个浮点参数在 xmm0-xmm7 中作为标量传递。
  • 剩余的不适合的参数按 C 顺序被压入堆栈。堆栈会根据需要填充以保持 rsp 与 16 字节对齐。
于 2010-06-12T19:44:17.930 回答
2

我用 C 编写了一个简单的程序,将其编译为汇编(使用 -S 开关),显然由 GCC 生成的汇编代码通过在寄存器中传递参数而不是被推送到堆栈来调用 OpenGL/SDL 函数。

这很正常:在x86-64上,传递参数时尽可能多地使用寄存器。

我发现这个文件有最全面的信息。

于 2010-06-12T19:39:11.603 回答
0

我相信这会有所帮助:

http://en.wikipedia.org/wiki/X86_calling_conventions#Borland_fastcall

Evaluating arguments from left to right, it passes three arguments via EAX, EDX, ECX. Remaining arguments are pushed onto the stack, also left to right.
于 2010-06-12T19:30:44.990 回答