How does this feature work?

While reading Hacking: Art of Exploitation (a wonderful book!), I came across this function:

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 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.
   } 
}

Here's the I / O table for the function:

= = = = = = = = = = = = = = = = = = = = = =
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
= = = = = = = = = = = = = = = = = = = = = =

Thus, I know that binary_print () converts decimal to binary.

But I don’t understand how exactly the function finds the correct answer. In particular:

  • What is a mask? How did the author come to the value 0xff000000? (0xff000000 seems to be approaching 2 ^ 32, the maximum int value in the system)
  • What is a shift? Why initialize it to 256 ^ 3? (It seems to me that this has something to do with the weight of the space in hexadecimal format)
  • What actually happens on these lines:
    • byte = (value and mask) / shift
    • byte and 0x80

In short, I would like to understand the binary_print () conversion method used.

+4
2

mask ( 32- ) 0xff000000 1 . shift 0x1000000 (.. 256 * 256 * 256).

byte = (value & mask)/shift - , , 0 0xff ( 8- ).

, unsigned numbers mask /= 256 mask = mask >> 8 ( ).

, , - (, gcc -Wall -g) (gdb) .

+6

, . , , , .

:

void binary_print(unsigned value) {
  for (unsigned mask = 0x80000000;  // High order bit
       mask;                        // While we have a bit
       mask >>= 1) {                // Shift right to next bit position
    if (value & mask) putchar('1'); // Bit is set: print a 1
    else              putchar('0'); // Bit is not set: print a 0
    if (mask & 0x01010100) putchar(' '); // A space if we just did the
                                         // low order bit of some byte
  }
}

, , , , , . printf overkill

+3

All Articles