请帮助我理解这种按位操作的指针值

Please help me understand this bit-wise manipulation of pointer values

本文关键字:位操作 指针 帮助      更新时间:2023-10-16

我不明白为什么addr被类型转换为long,然后用expression..基本上是计算peekAddr

的整行代码
void *addr;
char *peekAddr ;
peekAddr = (char *) ((long)addr & ~(sizeof(long) - 1 ) ) ;
peekWord = ptrace( PTRACE_PEEKDATA, pid, peekAddr, NULL ) ;
sizeof (long)     = (0)00000100
sizeof(long)-1    = (0)00000011
~(sizeof(long)-1) = (1)11111100

所以2位设置为0使地址对齐为4字节。此外,它主要用于当地址已经增加了sizeof(long)-1

它被强制转换为long,因为(1)除了强制转换它之外,您不能对void*进行任何操作,并且(2)在作者的平台上,void*值恰好适合long。他应该用uintptr_tsize_t来代替。

这段代码的作用:

sizeof(long) - 1

最有可能是3或7,取决于平台。

~(sizeof(long) - 1)

是一个位掩码,它选择除最后几位以外的所有位。

((long)addr & ~(sizeof(long) - 1))

addr向下舍入/对齐,以解决long大小的块。舍入是因为最后的lg(3)或lg(7)位是零,而其余的是从addr复制的(其中lg是整数二进制对数)。

这是一种非常丑陋,不可移植的方式

peakAddr = (char *)addr - ((uintptr_t)addr & -(uintptr_t)sizeof(long));

请注意,原始版本不仅依赖于指向long和返回的指针的成功往返转换,而且还依赖于size_t (sizeof运算符的结果类型)与long具有相同的宽度或宽度。如果不是,用~生成的位掩码将在上面的位扩展为零,并删除指针的一部分。

基本上,你应该在心里记住,无论你在哪个程序中找到这个,都是糟糕的代码,不要把它看作是一个想法的来源…

你基本上使peekAddr总是对齐的sizeof(长)地址。这行代码生成一个位掩码,并将其赋值到peek地址。这行从peekAddr中去掉最后一个长度为(long)-1的位。

hth

马里奥

这将在某些编译器上产生一个错误,sizeof(long) < sizeof(char*),例如Microsoft的。

sizeof(long)-1正在创建一个与long大小相对应的位掩码。这个技巧只适用于2的幂数。前面的~反转了它,所以现在它是所有地址位的掩码,当你试图对齐地址时,它应该保持不变。按位&清除地址的底部位以使其对齐。