How do I move the result of a mul of two floats in

2020-04-24 16:13发布

问题:

I am currently trying to multiply two floats, one that comes from a float vector (address stored in ebx) and against the value I stored in ecx.

I have confirmed that the input values are correct, however, if I multiply 32 and 1, for example, the value in EAX changes to 00000000 and the one in EDX to 105F0000. From my understanding of MUL, this happens because it is storing the high order bits of the result in EDX and the low order ones in EDX. Question is, how do I move the result into an output variable (returnValue) ? Here is the code snippet in question:

AddColumnsIteration:
    cmp esi, 4 // If we finished storing the data
    jge NextColumn  // Move to the next column
    mov eax, [ebx][esi * SIZEOF_INT] // Get the current column
    mul ecx // Multiply it by tx
    add [returnValue][esi * SIZEOF_INT], eax // Add the data pointed at by eax to the running total
    inc esi // Element x, y, z, or w of a Vec4
    jmp AddColumnsIteration // Go back to check our loop condition  

I am aware that if I used x87 commands or SSE instructions, this would be orders of magnitude easier, but the constrains of the problem require pure x86 assembly code. Sorry if this seems kinda basic, but I am still learning the idiosyncracies of assembly.

Thank you in advance for the help and have a nice day

回答1:

You’re multiplying the representations of the floating-point numbers as integers, rather than the floating-point numbers themselves:

 1.0 = 0x3f800000
32.0 = 0x42000000

       0x3f800000 * 0x42000000 = 0x105f000000000000

To actually do floating-point arithmetic, you need to do one of the following:

  • Use x87.
  • Use SSE.
  • Write your own software multiplication which separates the encodings into a signbit, exponent, and significand, xors the signbits to get the sign bit of the product, adds the exponents and adjusts the bias to get the exponent of the product, multiplies the significands and rounds to get the significand of the product, then assembles them to produce the result.

Obviously, the first two options are much simpler, but it sounds like they aren’t an option for some reason or another (though I can’t really imagine why not; x87 and SSE are "pure x86 assembly code”, as they’ve been part of the ISA for a very long time now).