扩展内联汇编:输入和输出的相同变量

Posted

技术标签:

【中文标题】扩展内联汇编:输入和输出的相同变量【英文标题】:extended inline assembly: same variable for input and output 【发布时间】:2013-04-13 23:09:36 【问题描述】:

我决定开始学习一些内联汇编,但是我遇到了一个简单的问题,我无法找到明确的答案。

以我在教程中找到的以下简单示例为例,该示例执行简单的加法:

int one,two,out;

one = 1;
two = 2;

__asm__ ( "add eax, ebx;" : "=a" (out) : "a" (one) , "b" (two) );

请注意,在使用 intel 语法一段时间后,为了我自己的理智,我将 GCC 配置为使用 intel 语法而不是 AT&T。

现在假设我想省去“out”变量,而只将输出存储在“one”中(或“two”中)。

我该怎么做?

【问题讨论】:

【参考方案1】:

使用

 __asm__ __volatile__(" add %0, %2": "=r" (one): "0"(one), "r" (two) )

通过使用“=r”和“r”,您不必强制编译器使用特定寄存器,这有助于寄存器分配。 “0”表示“与(输出)参数 0 使用相同”。

Edit3:two 参数在%2 中,而不是在%1 中,这只是one 的第二个副本(与%0 相同的寄存器)。当应该使用单时,还修复了双 %

Edit2:我还添加了__volatile__ 以确保编译器不会移动或省略汇编代码,如果编译器认为您的代码没有做任何有用的事情,就会发生这种情况[通常是因为它不会产生编译器的输出稍后使用]。使用__volatile__ 可以保证编译器不会移动或删除汇编代码。

Edit1:修正语法。

【讨论】:

使用此示例,这似乎将变量“two”添加到自身,给我一个结果 4,而不是预期的结果 3。如果我使用“=a”,它也会这样做用于“一”变量,“b”用于“二”变量 是的,我很愚蠢。今天早上开始的太早了,现在是半夜半是我的借口,我会坚持下去...... ;) 请参阅上面的编辑文本。 没问题,它有效,但我接受了另一种解决方案,因为它更干净【参考方案2】:
__asm__ ( "add eax, ebx;" 
            : "+a" (one) 
            : "b" (two) );

"+" 修饰符表示一个“读/写”操作数(并且必须在输出约束中使用)。

【讨论】:

以上是关于扩展内联汇编:输入和输出的相同变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有扩展内联 asm 的情况下在 gcc 内联汇编中声明和初始化局部变量?

GCC内联汇编常见陷阱

内联汇编约束修饰符 = 和 +

GCC 扩展内联汇编简介

输出是不是总是由 C 中的内联汇编中的 %eax 寄存器确定?

优化系列汇编优化技术:x86架构内联汇编及demo