0

Having a slight register problem with div using inline asm under vs2010.

testScore and gradeScale are integers.

_asm
{
   mov  eax, testScore      //student's score - let's test 36
   mov  ebx, 40             //max possible score of 40

   xor  edx,edx             //prevented an integer overflow error.

   div  ebx                 //divide and multiple by 100 to get letter grade. 
                            //SHOULD BE 36/40 = .9 but 36 is in EDX instead.
   
   imul edx, 100            //should now be 90 in EDX, but it's at 3600.
   mov  gradeScale, edx    //move result to gradeScale
 }

36/40 should place 0 in EAX and .9 in EDX. then multiply that by 100 and store it to gradescale.

Should be simple but I'm missing something here...

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Arcath
  • 51
  • 6
  • What is `xor edx,edx` used for please? – barak manos Apr 19 '14 at 18:36
  • I was getting an integer overflow error and [another post](http://stackoverflow.com/questions/13391152/asm-x86-integer-overflow) i read suggested it was because EDX wasn't initialized. I am really new with ASM so I decided to try it and it worked. – Arcath Apr 19 '14 at 18:41
  • You should have consulted the instruction set reference to see how div works. – Jester Apr 19 '14 at 18:54

2 Answers2

2

EAX and EDX are integer registers, so DIV is an integer division. You cannot expect a rational number like 0.9. DIV gives you in EDX the remainder of an integer division. You can use the FPU floating point registers or - better - multiply testScore with 100 before DIV:

#include <stdio.h>

int main ( void )
{
    int testScore = 36;
    int gradeScale = 0;

    _asm
    {
        mov  eax, testScore      //student's score - let's test 36
        mov  ebx, 40             //max possible score of 40

        imul eax,100

        xor  edx,edx             //prevented an integer overflow error.
        div  ebx                 // EAX = EDX:EAX / EBX Remainder: EDX

        mov  gradeScale, eax    //move result to gradeScale
    }


    printf("%i\n",gradeScale);

    return 0;
}
rkhb
  • 14,159
  • 7
  • 32
  • 60
1

It's been a while, that I code Assembler, but I think that the value in EDX is the remainder of 36/40. The register work only with integers, you cannot get floating point values like 0.9.

Edit: And by the way xor EDX, EDX set the register to 0. See: XOR register,register (assembler)

Community
  • 1
  • 1
Basti
  • 130
  • 1
  • 9
  • And the point if zeroing edx is that the `div ebx` uses the 64 bit quantity `edx:eax` as dividend. – Jester Apr 19 '14 at 18:55