如果我在Windows VC ++中有以下代码:
DWORD somevar = 0x12345678; _asm call dword ptr [somevar]
用AT&T语法怎样才能在GCC inline-assembly中做同样的事情?
__asm__ __volatile__ ( "call dword ptr [%%edx]" : : "d" (somevar) );
我试过这样的东西,但它会产生一个“垃圾”错误…
然后我尝试将somevar
传递给某些寄存器,然后将其转换为dword
, ptr
等,但是我无法使其工作。
更新:我发现了一些有用的东西,就好像我们在这种情况下必须使用括号而不是括号,并且发现了一些与lcall
东西。 但我仍然不明白如何重现dword ptr
。
AT&T汇编程序语法不使用DWORD PTR或类似的东西。 操作数长度通常取自寄存器名称(有一个提供后缀助记符的选项),而后者又来自您给asm()的C操作数的大小。 这是内联汇编程序的一个非常好的属性,因为这意味着如果为x86_64 或 i386体系结构编译此示例,就会运行该示例。 在第一种情况下,程序集变成类似call *%rdx
东西,在第二种情况下它变成call *%edx
:
#include <stdio.h> void p() { puts("Hallo"); } typedef void (*fp)(); int main() { fp var=&p; var(); // put 'var' in a register, the '*' says call indirect: asm volatile ("call *%0"::"r"(var)); }
您可以阅读GCC生成的代码(尝试使用-S编译)以学习AT&T语法。 也尝试谷歌一些介绍,如:
警告:使用gcc进行内联汇编不是一件小事。 这是因为,除了大多数其他编译器,它被设计为与优化器一起工作。 你必须真正理解约束(“r”)是什么意思和做什么,否则你会以你无法想象的方式破坏你的代码。 在回答什么是“早期的破坏者”之前,甚至不要考虑使用它。