Search code examples
assemblyx86nasmradixnumber-systems

Writing to bl and bh


I am trying to understand the following behavior:

mov bl, 51 ; now print $ebx in gdb returns 51         
mov bh, 52 ; now it is 13363 but I thought it would be 5251

Why? I use Linux nasm on Intel x86


Solution

  • When you print a 16-bit integer, you don't separately convert the two bytes to decimal strings and concatenate them. You have to convert the entire 16-bit number to a string of place-value digits.

    The reason it doesn't work is that base 10 is not a power of 2. For bases that evenly divide 256, like hex, doing each byte (or 4-bit nibble for hex) separately does work.

    e.g. bh=0x34 : bl=0x33 gives you 52*256 + 51 = 0x3433

    This is one reason that converting to hex is so much easier (as well as more efficient) than converting to decimal: you can start with the most-significant digit first.

    For bases that aren't congruent to 256 (if that's the right terminology), dividing by the radix (e.g. dividing by 10 to get the low digit) changes the upper bits


    BTW, note that writing to BL and BH doesn't zero the upper 2 bytes of EBX. The 16-bit concatenation of BH:BL is addressable as BX, not EBX. But if the upper 2 bytes of EBX are zero, then printing EBX is the same as BX.