Search code examples
assemblyx86nasm32bit-64bitendianness

x86 assembly 64-bit values with 32-bit program


If we multiply two very large 32-bit values the result can end up in registers EDX and EAX, with EDX holding the higher bits.

  • How do we perform operations on these 64-bit values and print them to the display?

I figured storing them was simply a matter of reserving two 32-bit memory spaces next to each other and storing EAX first then EDX second in the next 32-bit space. So with little-endianness we would have the lowest bit from EAX first and the highest bit from EDX held last across the two 32-bit memory spaces.

  • Is this right?
  • If so, what abstract thinking do we have to do after that in order to operate on the number?
  • Also could the 32-bit printf function be used somehow to display the value using only the original specifiers, such as "%d", "%u" or "%x"? Or do we have to make our own assembly process to print the value?

Solution

  • Your observations about storing the 64-bit value from EDX:EAX are correct.

    Further calculations that are easy enough are addition and subtraction:

    add  eax, ebx    ; EDX:EAX + ECX:EBX
    adc  edx, ecx
    
    sub  eax, ebx    ; EDX:EAX - ECX:EBX
    sbb  edx, ecx
    

    I guess what I really want to know is how does printf print a 64 bit value when we are working with 32 bit registers? What would that look like in assembly code? How would someone create that functionality themselves?

    From your comment it is clear that you really would like to do the conversion from 64-bit number EDX:EAX into a string of characters yourself.
    My answer at How to print a multiplication result in EDX:EAX in Assembly shows how to do just that.
    For additional info about the general approach to converting, be sure to read the answer for which a link was provided there. Don't feel intimidated by the mention of (old) DOS. Many principles don't change that much as technology evolves...