X86 如何将参数传递给C++;当我从内联程序集中调用函数时 >,我希望能够从C++ DLL调用函数。 由于某些原因,我想用C++代码中的一个AS-ASIC块调用它们。 我的问题是:我知道在调用函数之前,我必须按照函数调用约定指定的顺序将其参数推送到堆栈上。但是,我可以这样做吗: int a=5; double b = 5.0; __asm{ push b push a call functionAddress } 让我担心的是,我似乎记得汇编中的标准字大小是2字节,而C++中的int大小通常是4字节,而双字节的8字节。所以,在上面的例子中,我真的在推导出每个变量的全部值,或者仅仅是第一对字节。如果上面的代码不正确,正确的方法是什么?另外,如果我们调用的函数返回一个double,那么这个值存储在哪里?我假设它不能在寄存器中,因为它只能存储32位(4字节)。如果您能帮助解决这个问题,我们将不胜感激:)

X86 如何将参数传递给C++;当我从内联程序集中调用函数时 >,我希望能够从C++ DLL调用函数。 由于某些原因,我想用C++代码中的一个AS-ASIC块调用它们。 我的问题是:我知道在调用函数之前,我必须按照函数调用约定指定的顺序将其参数推送到堆栈上。但是,我可以这样做吗: int a=5; double b = 5.0; __asm{ push b push a call functionAddress } 让我担心的是,我似乎记得汇编中的标准字大小是2字节,而C++中的int大小通常是4字节,而双字节的8字节。所以,在上面的例子中,我真的在推导出每个变量的全部值,或者仅仅是第一对字节。如果上面的代码不正确,正确的方法是什么?另外,如果我们调用的函数返回一个double,那么这个值存储在哪里?我假设它不能在寄存器中,因为它只能存储32位(4字节)。如果您能帮助解决这个问题,我们将不胜感激:),x86,callstack,argument-passing,inline-assembly,X86,Callstack,Argument Passing,Inline Assembly,一般来说,您将推送计算机字的完整大小。这因芯片而异,但在32位英特尔上为4字节,在64位英特尔上为8字节(取决于编译器--Visual Studio仍然只支持IA32汇编--因此为4字节) 最好的答案是查看特定编译器的文档。32位x86体系结构会自动将推送到堆栈上的值填充到32位 有些事你必须牢记在心。如果您正在调用的函数使用了u_cdecl调用约定,那么您必须“弹出”您随后推送的内容。但是,对于u stdcall函数,您不能这样做 extern "C" int __cdecl fun

一般来说,您将推送计算机字的完整大小。这因芯片而异,但在32位英特尔上为4字节,在64位英特尔上为8字节(取决于编译器--Visual Studio仍然只支持IA32汇编--因此为4字节)


最好的答案是查看特定编译器的文档。

32位x86体系结构会自动将推送到堆栈上的值填充到32位

有些事你必须牢记在心。如果您正在调用的函数使用了u_cdecl调用约定,那么您必须“弹出”您随后推送的内容。但是,对于u stdcall函数,您不能这样做

extern "C" int    __cdecl   function1(int, double);
extern "C" double __stdcall function2(char, char*);

int a = 5;
double b = 5.0;
int retval1;
char c = '5';
char *d = "Hello";
double retval2;

__asm {
    push b
    push a
    call function1
    add esp, 4*2 // "pop" what we pushed
    mov retval1, eax
    push d
    push c
    call function2
    mov retval2, eax
}

要推送8字节值(如双精度值),您将无法使用常规的
push
指令。而且也不会将浮点参数(或双精度参数)推送到浮点堆栈上。您需要“手动”将这些fat参数放在堆栈上。例如,将π作为参数推送到函数f:

  __asm {
    FLDPI                    // load pi onto FP stack
    SUB ESP,8                // make room for double on processor stack
    FSTP QWORD PTR [ESP]     // store pi in proc stack slot (and pop from FP stack)
    CALL f
    ADD ESP,8                // clean up stack (assuming f is _cdecl)
  }

当你尝试它时发生了什么?我对double有一个问题:我在dll中为自己创建了一个测试函数,它接受一个双参数,如果输入大于5.0,则返回1。问题是,我尝试了几次从程序集中调用该函数,参数是7.45454,返回值并不总是相同。为了让你更加安心,在确定了它应该是什么之后,从C++中调用等效的调用,编译禁用的优化,然后查看程序集输出。它应该大致符合你正在做的。但是,那么,你会如何推动一个双?在C++中,它应该是8字节,对吗?