我无法理解为什么addr被长时间类型化,然后用表达式补充..基本上涉及peekAddr计算的整行
void *addr;
char *peekAddr ;
peekAddr = (char *) ((long)addr & ~(sizeof(long) - 1 ) ) ;
peekWord = ptrace( PTRACE_PEEKDATA, pid, peekAddr, NULL ) ;
答案 0 :(得分:5)
sizeof (long) = (0)00000100
sizeof(long)-1 = (0)00000011
~(sizeof(long)-1) = (1)11111100
所以2位设置为0使地址对齐为4个字节。另外,当地址已经增加sizeof(long)-1
时,它主要被使用答案 1 :(得分:4)
它被转换为long
,因为(1)你不能对void*
进行任何操作,除非在作者的平台上施放它和(2),void*
值只是如此恰好适合long
。他应该真的使用过uintptr_t
或size_t
。
这段代码的作用是什么:
sizeof(long) - 1
很可能是3或7,具体取决于平台。
~(sizeof(long) - 1)
是一个位掩码,可以选择除最后几位之外的所有位。
((long)addr & ~(sizeof(long) - 1))
向下舍入/对齐addr
以寻址long
大小的块。舍入发生是因为最后的lg(3)或lg(7)位为零,而其余位从addr
复制(其中lg是整数二进制对数)。
答案 2 :(得分:3)
这是一种非常丑陋,不可移植的做法
peakAddr = (char *)addr - ((uintptr_t)addr & -(uintptr_t)sizeof(long));
请注意,原始版本不仅依赖于指向long
和返回的指针的成功往返转换,还取决于size_t
(sizeof
运算符的结果类型)宽度相同或宽于long
。如果不是,则使用~
生成的位掩码将在高位中零扩展并消除指针的一部分。
基本上,你应该记住,你发现的任何程序都是错误的代码,而不是把它作为思想的来源......
答案 3 :(得分:1)
你基本上使peekAddr始终在sizeof(长)地址上对齐。该行生成一个位掩码和二进制文件,并将其设置为查看地址。 该行从peekAddr中删除最后一个sizeof(long)-1位。
HTH
马里奥
答案 4 :(得分:1)
这会在sizeof(long) < sizeof(char*)
的某些编译器上出现错误,例如Microsoft的。
sizeof(long)-1
正在创建与long
大小相对应的位掩码。这是一个仅适用于2的幂的数字的技巧。前面的~
反转它,所以现在它是所有地址位的掩码,当你试图对齐地址时它应该保持不变。按位&
正在清除地址的底部位以使其对齐。