GCC内联汇编:调用dword ptr

时间:2021-08-06 13:49:54

If I have the following code in Windows VC++:

如果我在Windows VC ++中有以下代码:

DWORD somevar = 0x12345678;
_asm call dword ptr [somevar]

How can I make the same thing in GCC inline-assembly, with AT&T syntax?

如何使用AT&T语法在GCC内联汇编中做同样的事情?

__asm__ __volatile__ (
    "call dword ptr [%%edx]" : :
    "d" (somevar)
);

I've tried something like this, but it generates an "junk" error...

我尝试过类似的东西,但它会产生“垃圾”错误......

And then I tried to pass somevar to some registers, and then convert it to dword, ptr, etc, but I couldn't get it to work.

然后我尝试将somevar传递给某些寄存器,然后将其转换为dword,ptr等,但我无法让它工作。

UPDATE: I found something that would be useful, like it seems that we have to use parenthesis instead of brackets in that case, and I found something with lcall to call as far. But I still can't understand how I can reproduce dword ptr.

更新:我找到了一些有用的东西,就好像在这种情况下我们必须使用括号而不是括号,并且我发现了一些用lcall来调用的东西。但我仍然无法理解我如何重现dword ptr。

1 个解决方案

#1


7  

You don't use DWORD PTR or anything like this with the AT&T assembler syntax. The operand length is usually taken from the register name (there's an option of provide a suffix with the mnemonic), which in turn comes from the size of the C operand you give to asm(). This is a very nice property of the inline assembler because it means that this example runs if you compile it for the x86_64 or the i386 architecture. In the first case, the assembly becomes something like call *%rdx, in the second case it becomes call *%edx:

您不使用DWORD PTR或类似的任何东西与AT&T汇编语法。操作数长度通常取自寄存器名称(可以选择提供带助记符的后缀),而后者又来自您给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));
}

You can read the code GCC generates (try compiling with the -S) in order to learn the AT&T syntax. Also try to google some intro, like:

您可以阅读GCC生成的代码(尝试使用-S编译)以了解AT&T语法。也尝试谷歌一些介绍,如:

WARNING: Inline assembly with gcc is not a trivial matter. This is because, other than with most other compilers, it is designed to work with the optimizer. You have to really understand what the constraints ("r") mean and do, or else you will break your code in ways you can't imagine. Don't even think about using it before you can answer what an "early clobber" is.

警告:使用gcc进行内联汇编并非易事。这是因为,除了大多数其他编译器之外,它还可以与优化器一起使用。你必须真正理解约束(“r”)的意思和作用,否则你将以你无法想象的方式破坏你的代码。甚至不要考虑使用它,然后才能回答“早期的咒语”。

#1


7  

You don't use DWORD PTR or anything like this with the AT&T assembler syntax. The operand length is usually taken from the register name (there's an option of provide a suffix with the mnemonic), which in turn comes from the size of the C operand you give to asm(). This is a very nice property of the inline assembler because it means that this example runs if you compile it for the x86_64 or the i386 architecture. In the first case, the assembly becomes something like call *%rdx, in the second case it becomes call *%edx:

您不使用DWORD PTR或类似的任何东西与AT&T汇编语法。操作数长度通常取自寄存器名称(可以选择提供带助记符的后缀),而后者又来自您给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));
}

You can read the code GCC generates (try compiling with the -S) in order to learn the AT&T syntax. Also try to google some intro, like:

您可以阅读GCC生成的代码(尝试使用-S编译)以了解AT&T语法。也尝试谷歌一些介绍,如:

WARNING: Inline assembly with gcc is not a trivial matter. This is because, other than with most other compilers, it is designed to work with the optimizer. You have to really understand what the constraints ("r") mean and do, or else you will break your code in ways you can't imagine. Don't even think about using it before you can answer what an "early clobber" is.

警告:使用gcc进行内联汇编并非易事。这是因为,除了大多数其他编译器之外,它还可以与优化器一起使用。你必须真正理解约束(“r”)的意思和作用,否则你将以你无法想象的方式破坏你的代码。甚至不要考虑使用它,然后才能回答“早期的咒语”。