从asm volatile调用中访问静态C变量

时间:2012-10-08 01:43:52

标签: c variables assembly volatile

当我尝试从asm volatile调用中直接访问静态变量 时,我收到一个未定义的引用错误。我认为有一种方法可以在不使用输入和输出寄存器的情况下执行此操作,但我的搜索结果是空的。

int main() {
   static unsigned int a = 0;
   __asm__ __volatile__("push a" : : :);
   return 0;
}

error: undefined reference to a

3 个答案:

答案 0 :(得分:2)

真的很老问题,但由于没有接受答案......

首先,我要说使用内联asm通常是bad idea。但如果你必须......

由于静态是在函数内声明的,因此gcc需要某种方法来区分main()中的一个名为Route::get('/sent/documents/{id}', [ 'uses' => '\App\Http\Controllers\DocumentController@readSentDocuments', 'as' => 'document.readSent', 'middleware' => 'auth', ]); 的静态变量和foo()中的一个静态变量。它是如何实现定义的,但在我的机器上构建时,它使用了名称a.2499。所以使用:

a

的工作。至少它做了一分钟。当我对周围的代码做了一些小改动时,它将其改为a.2500。当然,在执行此语句后不久,应用程序因堆栈损坏而崩溃。

但这种方法还存在其他问题。其中一些来自gcc docs中的这个陈述:

  

GCC不解析汇编程序指令本身而不解析汇编程序指令   知道它们的含义,甚至知道它们是否是有效的汇编输入。

结果,做:

__asm__ __volatile__("push a.2499" : : :);

不符合您的期望。即使是-O1的最小优化,也会将两个a++; __asm__ __volatile__("push a.2500" : : :); a++; 语句合并为一个a++。这样做是因为编译器无法看到asm中addl $2, a.2500(%rip)的使用情况,使用a作为输入会提供。

你可以'有点'通过将a声明为volatile来解决此问题。而且你可以(可能)通过使用全局来解决命名问题。

但最好的解决方案(如果你真的必须使用内联asm)只是指定a作为输入。我认为替代方案没有任何好处。

a

答案 1 :(得分:0)

尝试:

__asm__ __volatile__ ("push " (a) : : :);

答案 2 :(得分:-1)

伙计,从双引号中删除a

__asm__ __volatile__ ("push " (a) : : :);