【问题标题】:c inline assembly loading a register value to esp registerc内联汇编将寄存器值加载到esp寄存器
【发布时间】:2015-09-25 05:17:33
【问题描述】:

在代码中,我有以下声明

#if GCC == 1
#define SET_STACK(s)    asm("movl temp,%esp");
...
#endif

在代码中,恰好在一个地方使用了这个宏,编译器在该行上指示undefined reference to 'temp'

temp = (int*)some_pointer;
SET_STACK(temp);

temp 变量被声明为全局 volatile void 指针

volatile void* temp;

内联汇编有语法问题吗? 据我了解,内联程序集尝试加载 temp 的值(不是取消引用的值,而是指针本身)

【问题讨论】:

  • 有没有;在#define 的末尾?以前没见过
  • @UnderDog:分号不在定义后面,它是宏值的一部分。如果使用SET_STACK 宏,将插入asm 指令,包括分号。
  • @mastov:是的,但这是错误的,可能会破坏条件语句。
  • @Olaf:是的,考虑到它的使用方式,这是不必要的(不会说“错误” - 你只需要注意它)。只是说,分号与#define 指令的语法无关。根据您的计划,您甚至可能需要分号。
  • @mastov:(没有讨论“#define语法”,我什至没有提到。“......它可以有一个目的”:还在等待一个例子。唯一的目的这里的分号是把一个表达式变成一个语句。因为“调用者”已经给出了,所以实际上会有两个。两个相邻的分号有什么目的(除了引起麻烦) ?

标签: c pointers x86 cygwin inline-assembly


【解决方案1】:

您必须使用扩展汇编器将 C 操作数传递给汇编器:阅读manual。 (注意:由于您没有指定您使用的是哪个版本,所以我只是选择了一个。

不要忘记将汇编器中使用的寄存器添加到 clobber 列表。您还应该使汇编程序asm volatile

根据您的执行环境,手动操作堆栈指针可能是一个非常糟糕的主意!至少你应该把它放到__attribute__((naked)) 函数中,而不是宏中。宏中尾随的; 肯定是错误的,您将在宏之后已经有了它(2 个分号可能会破坏条件语句!

【讨论】:

  • You should also make the assembler asm volatile ,是不是意味着 asm volatile("汇编指令") ?
  • 注意:使用引号来引用,而不是反引号 - 这些用于代码片段。对于这个问题:当然。
  • 虽然您只是“选择”了一个版本,但 newer 文档得到了显着改进。
  • @DavidWohlferd:5.1 实际上并没有太多用于生产开发。我选择 4.8.2 的原因部分是随机的,但也因为它是 Ubuntu 14.04 LTS 的标准配置。
  • 这对于一般的文档来说是一个好点,但对于内联汇编来说就不是那么好了。所有新文档所做的都是更好地描述已经存在很长时间的功能。 4.x 文档描述了该功能以及如何使用它。
【解决方案2】:

如果你想在 GCC 内联汇编中使用 C 变量,你必须使用Extended ASM syntax,例如:

volatile int temp = 0;
asm("movl %0,%%esp"
  : /* No outputs. */
  : "rm" (temp)
);

【讨论】:

  • 谢谢,但是在 SHARC 内联汇编中,我使用了带有 _ 前缀的 c 变量,作为var 的 sucn 将用作 _var,这个内联汇编和汇编语法是否特定于装配工?是否有取决于汇编程序的语法? (我在 GAS 手册中阅读了有关 Intel 语法和 AT&T 语法的信息)
  • 不一定要有temp volatile。如果需要,将其留给呼叫者。请注意,volatile 阻止它成为寄存器。
  • @nmxprime:不同 CPU 的内联汇编程序怎么可能相同? SHARC 实际上是一个 DSP,其架构与普通 CPU 完全不同。对于asm 关键字及其语义:阅读 gcc 手册,这是一个 gcc 特定的扩展。这不是意味着它是非标准的吗?
  • 使用“+”而不是“=”有什么意义? asm 不读取现有值,它只是覆盖它。
  • @DavidWohlferd:它确实读取了temp 的值,以便将其复制到%esp
猜你喜欢
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 2021-03-21
  • 1970-01-01
相关资源
最近更新 更多