【发布时间】:2019-07-15 00:21:49
【问题描述】:
我正在尝试将 SP 寄存器的值存储到 C 中的变量中,这是我的代码:
int address = 0;
asm volatile ("STR sp, [%0]\n\t"
: "=r" ( address)
);
但在执行此代码后,操作系统会在屏幕上打印“Segmentation fault”消息并终止程序。谁能给我一个解决问题的建议?
【问题讨论】:
-
由于您指定了注册目的地,所以不要使用
STR...只需MOV %0, sp -
通常你可以只取本地变量的地址来获取当前函数堆栈帧中某处的地址。或使用
__builtin_frame_address(0)gcc.gnu.org/onlinedocs/gcc/Return-Address.html。但是,是的,使用内联汇编你肯定只想要mov到%0。一般使用intptr_t address,而不仅仅是int,来保存指针,虽然是在32位ARM上int可以保存指针。 -
对于内联 asm 更好的版本:
register void* address __asm__("sp"); __asm__ __volatile__("" : "=r" (address)); -
@Jester:你会认为这很好,但 ARM gcc 实际上会通过首先执行
mov sp, r3来破坏 SP。 godbolt.org/z/-DEbAD。我在玩"+r"(sp)作为Print out value of stack pointer 的可能答案 - 使用"+r"而不是"=r",我们得到 mov r3,sp / mov sp,r3 / mov r0,sp 所以它在 ARM 上仍然很糟糕。但它适用于 x86,它允许 GCC 将 RSP 直接存储到内存目标,如果需要,无需使用 reg-regmov。 -
@PeterCordes 看起来像回归。我的 gcc 4.3.3 工作正常。
标签: c assembly arm inline-assembly