在阅读Hacking: The Art of Exploitation(一本好书!)时,我遇到了这个函数:
void binary_print(unsigned int value) {
unsigned int mask = 0xff000000; // Start with a mask for the highest byte.
unsigned int shift = 256*256*256; // Start with a shift for the highest byte.
unsigned int byte, byte_iterator, bit_iterator;
for(byte_iterator=0; byte_iterator < 4; byte_iterator++) {
byte = (value & mask) / shift; // Isolate each byte.
printf(" ");
for(bit_iterator=0; bit_iterator < 8; bit_iterator++) { // Print the byte's bits.
if(byte & 0x80) // If the highest bit in the byte isn't 0,
printf("1"); // print a 1.
else
printf("0"); // Otherwise, print a 0.
byte *= 2; // Move all the bits to the left by 1.
}
mask /= 256; // Move the bits in mask right by 8.
shift /= 256; // Move the bits in shift right by 8.
}
}
这是函数的输入输出表:
= = = = = = = = = = = = = = = = = = = = = =
INPUT : OUTPUT
= = = = = = = = = = = = = = = = = = = = = =
0 : 00000000 00000000 00000000 00000000
2 : 00000000 00000000 00000000 00000010
1 : 00000000 00000000 00000000 00000001
1024 : 00000000 00000000 00000100 00000000
512 : 00000000 00000000 00000010 00000000
64 : 00000000 00000000 00000000 01000000
= = = = = = = = = = = = = = = = = = = = = =
由此我知道 binary_print() 将十进制转换为二进制。
但我不明白函数究竟是如何找到正确答案的。具体来说:
- 什么是面具?作者是如何得出值 0xff000000 的? (0xff000000 似乎接近 2^32,即系统中 int 的最大值)
- 什么是转变?为什么要初始化为256^3? (对我来说,这似乎与十六进制的位置权重有关)
- 这些行中实际发生了什么:
- byte = (value & mask)/shift
- 字节 & 0x80
简而言之,我想理解 binary_print() 用来做的方法 转换。
最佳答案
作为位掩码
(在 32 位机器上)0xff000000
的最高字节全为 1。并且 shift
被初始化为 0x1000000
(即 256*256*256)。
byte = (value & mask)/shift
使用 bit-and 来提取掩码的位,然后移动它们以获得 0 和 0xff 之间的值(适合 8 位字节) .
请注意,对于unsigned
数字,mask/= 256
与mask = mask >> 8
相同(编译器通常会优化从第一到第二)。
准确理解正在发生的事情的最好方法可能是编译带有所有警告和调试信息的代码(例如 gcc -Wall -g
)并使用调试器 (gdb
) 逐步运行您的程序并显示相关状态。
关于c - 这个功能是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20113590/