1
votes

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
I have no clue what caused the negative rating - Bruno Ayllon
First check that your code works! mul seems to be missing an operand. And you are trying to use integer arithmetic without any decoding and encoding of floating point values (wrong). For the output, how does your C++ environment want it? You may have an output address too, or if the operation is "*=", then overwrite the old vector with the rescaled one. - user877329
MUL is not missiong an operand, it takes whatever value you give it and multiplies the value stored in EAX by it. What do you mean encoding or decoding of floating point values (as I said, I am new to assembly) ? The result is outputted into a Vec4, simply a struct with 4 floats, all initialized to zero. So basically, the code multiplies a 4x4 matrix by a 4x1 vector and stores it in a Vec4 output. - Bruno Ayllon
The output Vec4 is a local variable. - Bruno Ayllon
Ok mul has only one operand so you are right there. But mul is an integer instruction. If you pass floating point values in EAX and ECX they are treated as integers. So the product is the product of the integers that represents the floats which is not the same. 32 encoded as a float is 0x42000000 not 0x20 and 1 is encoded as 0x3f800000. Multiplying gives 0x105f000000000000 and not 32! You have to either use fmul or invent your own fmul to get it right. - user877329

1 Answers

6
votes

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