C 读取ARM中的堆栈指针值

C 读取ARM中的堆栈指针值,c,assembly,arm,inline-assembly,C,Assembly,Arm,Inline Assembly,我试图将SP寄存器的值存储到C中的一个变量中,下面是我的代码: int address = 0; asm volatile ("STR sp, [%0]\n\t" : "=r" ( address) ); 但在执行此代码后,操作系统会在屏幕上打印“分段错误”消息并终止程序。有谁能给我一个建议来解决这个问题吗?在内联汇编中,你甚至不应该碰堆栈指针。这是一个禁忌 一开始你不应该这么做。把它留给编译器吧 如果您没有更改堆栈指针或在堆栈上写入任何内容,那么它可能会起作用,您只是使用

我试图将SP寄存器的值存储到C中的一个变量中,下面是我的代码:

int address = 0;
asm volatile ("STR sp, [%0]\n\t"
     : "=r" ( address)
     );

但在执行此代码后,操作系统会在屏幕上打印“分段错误”消息并终止程序。有谁能给我一个建议来解决这个问题吗?

在内联汇编中,你甚至不应该碰堆栈指针。这是一个禁忌

一开始你不应该这么做。把它留给编译器吧

如果您没有更改堆栈指针或在堆栈上写入任何内容,那么它可能会起作用,您只是使用了错误的指令

要执行的操作:将堆栈指针复制到32位寄存器

操作:将堆栈指针本身存储到地址0。=>分段错误


STR sp[%0]\n\t
替换为
mov%0,sp\n\t

因为您指定了寄存器目标,所以不要使用
STR
。。。just
MOV%0,sp
通常,您可以只获取本地变量的地址,以获取位于当前函数堆栈帧中某处的地址。或者使用
\u内置\u框架\u地址(0)
。但是,使用内联asm,您肯定只需要
mov
%0
。通常使用
intptr\t address
,而不仅仅是
int
,来保存指针,尽管32位ARM
int
上的yes可以保存指针。对于内联asm更好的版本:
寄存器无效*地址(“sp”)__asm___;volatile___(“:”=r(地址))
@Jester:你可能认为这很好,但ARM gcc实际上是通过先执行
mov SP,r3
来破坏SP的。我在玩
“+r”(sp)
作为可能的答案-用
“+r”
而不是
“=r”
,我们得到了mov r3,sp/mov sp,r3/mov r0,sp,所以在ARM上仍然很糟糕。但它在x86上运行得很好,在x86中,它允许GCC将RSP直接存储到内存目标,而不需要reg reg
mov
,如果它愿意的话。@PeterCordes看起来像一个回归。GCC4.3.3i运行良好。
address=0
初始值设定项可以被优化掉,在寄存器中留下任何垃圾。这是一个仅输出的约束,而不是
“+r”
,因此任何先前对
地址的赋值在该点都是无效的。因此存储地址很可能是一些垃圾,而不是0。