Skip to content

Latest commit

 

History

History
103 lines (98 loc) · 5.33 KB

24.working_with_bits_operators_results.md

File metadata and controls

103 lines (98 loc) · 5.33 KB
  • Let's take a look at the assembly instructions.
  24:bitwise_16bit_color.cpp ****         uint32_t hex = 0;
 565                            .loc 6 24 0
 566 00cf C745C400              movl    $0, -60(%rbp)
 566      000000
  25:bitwise_16bit_color.cpp ****
  26:bitwise_16bit_color.cpp **** // set red value from bit 0 ~ 4
  27:bitwise_16bit_color.cpp ****         hex |= (r & 0x1F);
 567                            .loc 6 27 0
 568 00d6 8B45B8                movl    -72(%rbp), %eax
 569 00d9 83E01F                andl    $31, %eax
 570 00dc 0945C4                orl     %eax, -60(%rbp)
  28:bitwise_16bit_color.cpp ****
  29:bitwise_16bit_color.cpp **** // set green value from bit 5 ~ 10
  30:bitwise_16bit_color.cpp ****         hex |= ((g & 0x3F) << 5);
 571                            .loc 6 30 0
 572 00df 8B45BC                movl    -68(%rbp), %eax
 573 00e2 C1E005                sall    $5, %eax
 574 00e5 25E00700              andl    $2016, %eax
 574      00
 575 00ea 0945C4                orl     %eax, -60(%rbp)
  31:bitwise_16bit_color.cpp ****
  32:bitwise_16bit_color.cpp **** // set blue value from bit 11 ~ 15
  33:bitwise_16bit_color.cpp ****         hex |= ((b & 0x1F) << 11);
 576                            .loc 6 33 0
 577 00ed 8B45C0                movl    -64(%rbp), %eax
 578 00f0 C1E00B                sall    $11, %eax
 579 00f3 0FB7C0                movzwl  %ax, %eax
 580 00f6 0945C4                orl     %eax, -60(%rbp)
  • It seems that the compiler used following instructions to implement.
instruction opcode expected behavior example
movl C7 set a value to a memory location (32bit) movl $0, -60(%rbp)
movl 8B copy a value at a memory location to another (32bit) movl -72(%rbp), %eax
andl 83 bitwise and operation to a memory location (32bit) andl $31, %eax
orl 09 bitwise or operation to a memory location (32bit) orl %eax, -60(%rbp)
sall C1 bitwise left shift to a memory location (32bit) sall $5, %eax
movzwl 0F expand 16 bit value to longer unsigned integer movzwl %ax, %eax
  • It also seems that the result of the operation remains at the latter of the two operands.
  • Let's take a look at how to designate operands: values or memory locations.
operand designation example
direct value decimal number $0, $31
eax register general purpose register eax (32bit) %eax
ax register general purpose register ax (16bit) %ax
pointer memory at address -60(%rbp), -72(%rbp)
rbp register base pointer register (64bit) %rbp
  • Now let's look at the first a few lines of the assembly code above.
  24:bitwise_16bit_color.cpp ****         uint32_t hex = 0;
 565                            .loc 6 24 0
 566 00cf C745C400000000        movl    $0, -60(%rbp)
  • The last line is the machine code / assembly translation from the C/C++ code of the first line.
machine language code meaning
00cf the start location of this machine code
C7 movl immediate value
45 (%rbp) addressing using base pointer
C4 offset from %rbp
$$ 60_{10}=00111100_2 \ 11000100_2 = C4_{16} $$
0000 0000 immediate value to write to -60(%rbp) location
  • This line would initialize uint_32t variable hex with zero.
  • Now let's take a look at the next a few lines
  25:bitwise_16bit_color.cpp ****
  26:bitwise_16bit_color.cpp **** // set red value from bit 0 ~ 4
  27:bitwise_16bit_color.cpp ****         hex |= (r & 0x1F);
 567                            .loc 6 27 0
 568 00d6 8B45B8                movl    -72(%rbp), %eax
 569 00d9 83E01F                andl    $31, %eax
 570 00dc 0945C4                orl     %eax, -60(%rbp)
  • The C/C++ line here tries to copy the lower 5 bits of variable r to hex.
  • The first assembly instruction copies a 32 bit value to eax register.
  • The second instruction applies 32bit bitwise and operation to eax register. As $31_{10} = 11111_2$, all bits between 31 ~ 5 would be 0.
  • The third instruction carrys out bitwise or operation to uint32_t variable hex with the value of eax register.
  • THe following lines are similar, too.
  28:bitwise_16bit_color.cpp ****
  29:bitwise_16bit_color.cpp **** // set green value from bit 5 ~ 10
  30:bitwise_16bit_color.cpp ****         hex |= ((g & 0x3F) << 5);
 571                            .loc 6 30 0
 572 00df 8B45BC                movl    -68(%rbp), %eax
 573 00e2 C1E005                sall    $5, %eax
 574 00e5 25E0070000            andl    $2016, %eax
 575 00ea 0945C4                orl     %eax, -60(%rbp)
  • Let's focus on the following two lines.
 573 00e2 C1E005                sall    $5, %eax
 574 00e5 25E0070000            andl    $2016, %eax
  • Here,
    sall $5, %eax
    intend to shift the 32bit content of eax to the left by five binary digits.
  • In the third line is as follows.
    andl $2016, %eax
  • Because
    $2016_{10} = 07e0_{16}= 0000 0111 1110 0000_2$
    this would turn off bits of eax except 6 bits associated with g.
  • Compare with C/C++ line. Is the order same? Why or why not?