GCC内联汇编中的等号符号"g = g"是什么意思/作用?

8

我不确定这个内联汇编是做什么的:

asm ("mov %%esp, %0" : "=g" (esp));

尤其是: "=g" (esp)这部分内容。

2
这不是一个答案,但如果你查看此页面,你可以相当好地自学它的含义:http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html -只需在页面上搜索第一个%0即可。 - John Zwinck
2个回答

9
"=g(esp)"定义了内联汇编的输出。 g 告诉编译器可以使用任何通用寄存器或内存来存储结果。 (esp) 表示结果将存储在名为 esp 的c变量中。 mov %%esp,%0 是汇编命令,它只是将堆栈指针移动到第0个操作数(输出)。 因此,这个汇编程序只是将堆栈指针存储在名为 esp 的变量中。"

这让我产生了几个问题:1)内联汇编有“输出”是什么意思?2)可以使用任何通用寄存器,如eax、ebx、ecx等来存储结果吗?我认为内联汇编只允许程序员在代码流中放置一些“自定义”的汇编代码。如果是这样的话,它似乎会将0放入堆栈指针寄存器中(即mov esp,0)。 - ladookie
2
  1. 是的,任何通用寄存器都可以。
  2. GCC使用AT&T语法,这意味着第一个操作数是源,第二个操作数是目标。 1,3) 内联汇编可以被视为内联函数。它可以有多个输入和输出,允许汇编和c代码相互通信。参数按编号进行访问。%0表示第0个参数。编译器将自动决定应该使用什么并将其替换为代码,然后添加代码将其从那里移动到变量中。
- ughoavgfhw
@ughoavgfhw:顺便夸一下你的速度,加1分 :)。 - Nemo
这真是太奇怪了,但我想它的目的是为了在代码中将特定寄存器分配给变量吧?我现在终于明白了。所以如果我想要将寄存器eax的值存储在我创建的变量'x'中,我应该写asm("mov %%eax, %0" : "=g" (x));对吗? - ladookie
实际创建的汇编代码会类似于 mov %eax, x 或者其他什么吗?那为什么不直接写 `asm("mov %%eax, x") 呢?我们为什么需要这个 "=g" 的东西呢?我想我问的是,难道我们不能找出获取存储在变量中的寄存器所需的汇编指令,并使用它来代替吗? - ladookie
@ladookie 这就是gcc内联汇编的工作原理。由于允许内存引用,编译器可能会这样做(直接将值移动到变量中)。尝试使用gcc -S查看编译器创建的汇编代码,并查看它实际上执行了什么操作。您还可以尝试不同的优化级别以查看它的操作。 - ughoavgfhw

9
如果你想了解更详细的信息,请阅读关于扩展汇编的GCC文档。
简短的答案是将x86堆栈指针(%esp寄存器)移动到名为“esp”的C变量中。“=g”告诉编译器可以替换汇编代码中的%0操作数的类型。(在这种情况下,它是“通用操作数”,这意味着几乎任何寄存器或内存引用都是允许的。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接