代码:
int main(void) {
register int rsp asm("rsp");
int temp=rsp;
printf("\n (rsp)%p \n", rsp);
printf("\n (temp)%p \n", temp);
printf("\n (void*)(rsp)%p \n", (void*)rsp );
printf("\n (void*)(temp)%p \n", (void*)temp );
return 0;
}
输出:
(rsp)0xffffcbe0
(temp)0xffffcbe0
(void*)(rsp)0xffffffffffffcbe0
(void*)(temp)0xffffffffffffcbe0
我怀疑这是一个愚蠢的问题,但为什么指针的值会在演员之后发生变化?我试图投射到不同的类型,我总是得到相同的偏移量。 谢谢。
答案 0 :(得分:2)
但是为什么在施法后指针的值会发生变化?
int
和rsp
是int
,不是指针。
"%p"
使用int
是未定义的行为。
printf("\n (rsp)%p \n", rsp); // UB
printf("\n (temp)%p \n", temp); // UB
然而,让我们假设转换为unsigned
的值是由OP打印的。
printf("\n (rsp)0x%x \n", (unsigned) rsp); // (rsp)0xffffcbe0
printf("\n (temp)0x%x \n", (unsigned) temp); // (temp)0xffffcbe0
当代码将int
指针转换为register int rsp asm("rsp");
时,它可能会失去重要性@David Wohlferd。将int
转换为指针时,会出现各种转换机制,例如符号扩展,以应对窄int
。 "%p"
具有特定于实现的格式。
要明确:OP的代码当然不会打印原始asm("rsp")
的地址。 (编译器特定扩展名)。
C提供可选的整数类型(u)intptr_t
,它提供从/到等效整数和对象指针的转换。要将对象指针保存为整数,请使用这些类型。不幸的是,C缺少用于打印非void*
指针和(u)intptr_t
的值的锁定打印说明符,因此在下面进行转换。
#include <stdint.h>
#include <stdio.h>
char *s = "rsp";
printf("pointer %p\n", (void *) s);
uintptr_t i_ptr = (uintptr_t) s;
printf("integer 0x%jX\n", (uintmax_t) i_ptr);