【问题标题】:Percentage (%) sign in GNU inline assembly (asm in C)GNU 内联汇编(C 中的 asm)中的百分比 (%) 符号
【发布时间】:2019-04-13 20:03:36
【问题描述】:

这些代码行应该做什么?

mov ebx, %1

mov ecx, %0

我知道 % 表示指针,但我需要更多解释。为什么是 %1 和 0 - 这些具体数字?

【问题讨论】:

  • 这是c代码中的内联汇编吗?
  • 是的,没错
  • 这样的代码通常是内联汇编效率低下的标志。因为它是 ebx 而不是 %%ebx,所以这是 -masm=intel 语法,将操作数移动到 那些寄存器。而不是这样,只需告诉编译器您希望在这些寄存器中首先使用"c"(var0), "b"(var1) 进行输入。见stackoverflow.com/tags/inline-assembly/info

标签: c gcc assembly x86 inline-assembly


【解决方案1】:

在 AT&T 语法中,寄存器使用百分号,然后是寄存器名称,即%eax。您用数字显示的那些在汇编中没有意义,它们在内联汇编中用于引用输入和输出操作数。

int i = 5;
int j;
asm ("mov %1, %0" : "=r"(j) : "r"(i)); //AT&T. Swap operands for Intel syntax

这会将ij 分别声明为输出和输入参数。 q 表示任何通用寄存器都可以。除非你真的需要一个特定的寄存器,否则你应该总是让你的编译器选择任何方便的东西。因为你事先不知道你得到了哪些寄存器,所以它们被分配了一个从 0 开始的数字。%0 是第一个参数,在这种情况下,输出参数 j%1 是输入参数,i .

【讨论】:

  • 您的操作数被反转为 AT&T 语法。它应该是 asm ("mov %1, %0" : "=q"(j) : "q"(i)) 。您的可能似乎有效,因为编译器可能对输入和输出约束使用了相同的寄存器。我还推荐r 而不是q。这将允许所有通用寄存器,无论是 64 位还是 32 位代码(在 32 位代码中,q 约束只允许 EAX、EBX、ECX 和 EDX)。您也可以使用 ASM 执行此操作,而内联程序集中没有任何内容 asm ("" : "=r"(j) : "0"(i));
  • @MichaelPetch Your operands are reversed for AT&T [...] I'd also recommend r instead of q 你是对的,固定的。似乎我希望0 成为输入......其中一个也可能是内存操作数。 You can also do this move using ASM without anything in the inline assembly 不过,这会破坏示例的重点。
  • 我只是指出空的 asm 语句也可以,我明白以 mov 为例。
【解决方案2】:

%0 和 %1 是内联汇编块的前两个操作数。 我认为这不是常规的 x86,而是 gcc 的特殊功能。

请看这里:http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 2014-06-19
    相关资源
    最近更新 更多