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

在没有扩展内联asm的情况下,如何在gcc内联程序集中声明和初始化局部变量?,gcc,scope,inline-assembly,local-variables,Gcc,Scope,Inline Assembly,Local Variables,我知道这是一个非常基本的问题,但我真的被困在这个问题上了。事实上,我绝对是GCC语法的新手 我希望在不使用扩展内联程序集的情况下使用局部变量(带标签的堆栈地址)。类似于英特尔语法中的以下代码: data1db 100 MOV AL,数据1 我想这是GCC中可以替代的代码: intsomefunction(intx) { __反复无常( “功能1:” “.数据;” “.2字节$4数据1;” “.文本;” “pushq%rbp;” “movq%rsp,%rbp;” “movl var,%eax;”

我知道这是一个非常基本的问题,但我真的被困在这个问题上了。事实上,我绝对是GCC语法的新手

我希望在不使用扩展内联程序集的情况下使用局部变量(带标签的堆栈地址)。类似于英特尔语法中的以下代码:

data1db 100
MOV AL,数据1
我想这是GCC中可以替代的代码:

intsomefunction(intx)
{
__反复无常(
“功能1:”
“.数据;”
“.2字节$4数据1;”
“.文本;”
“pushq%rbp;”
“movq%rsp,%rbp;”
“movl var,%eax;”//这是错误源
“popq%rbp;”
“leveq;”
“retq;”
); 
}
但此代码会导致此错误:

未找到架构x86_64的符号

我可以在x86中使用全局变量,但在x64或x86_x64中也会得到相同的结果

设置:LLVM 4.1;Xcode 4中使用的Cocoa


正确的语法是什么?

GCC内联汇编程序不支持局部变量,请使用

如果您对AT&T的语法感到不舒服,有几种方法可以解决这个问题


这是一个很好的方法。

但是您如何知道变量在堆栈上的起始位置?你只是假设gcc在开始时创建了一个新的堆栈框架,并假设第一个局部变量就在这个框架的正上方还是什么?@greatwolf:不,这个建议完全是垃圾。不要试图硬编码gcc如何进行堆栈布局。即使您确实知道它相对于堆栈指针的位置,编译器也会假定您没有修改它。必须将扩展内联asm与输入/输出操作数一起使用,才能安全地读取、写入或读+写局部变量。除非您喜欢编写只在特定版本的gcc的未优化调试版本中工作的代码,并且在更改周围的代码时仍然会中断。@PeterCordes谢谢,我可能在那里大声思考过,我将从回答中删除该部分也相关:-您永远不应该在函数中使用基本asm。仅在全局范围内,或在
\uuuu属性((裸))
函数中,您不能使用C语句或扩展asm,您可以编写整个函数体,包括
ret
,并自行处理调用约定。从技术上讲,执行asm(“lfence”)或不影响内存或寄存器的操作是安全的,但通常您希望知道它是按wrt排序的。内存访问和周围C中的东西。顺便说一句,
asm(“movl$123,global_var”)
是不安全的:它不会告诉编译器您修改了内存。它将编译和组装没有错误,但它仍然是不安全的,并且会损坏。请注意,
data1db100
是静态存储。Like
staticchardata1=100
静态局部变量(自动存储类)存在于寄存器中,如果寄存器用完或需要获取它们的地址,则位于堆栈上。因此,同一个函数可以在多个线程中运行,而无需自上而下:它是可重入的。