内联asm中的寄存器的除法问题

时间:2014-04-19 18:33:12

标签: assembly division

在vs2010下使用内联asm对div有轻微的注册问题。

testScore和gradeScale是整数。

_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应该在EAX中放置0,在EDX中放置.9。然后将其乘以100并将其存储到年级。

应该很简单,但我在这里遗漏了一些东西......

感谢您的光临。

2 个答案:

答案 0 :(得分:1)

我已经有一段时间了,我编写了汇编程序,但我认为EDX中的值是36/40的剩余部分。寄存器只能用整数运算,你不能得到像0.9这样的浮点值。

编辑:顺便说一句xor EDX,EDX将寄存器设置为0.参见:XOR register,register (assembler)

答案 1 :(得分:1)

EAX和EDX是整数寄存器,因此DIV是整数除法。你不能指望像0.9这样的理性数字。 DIV在EDX中为您提供整数除法的余数。您可以使用FPU浮点寄存器或 - 更好 - 在DIV之前将testScore乘以100:

#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;
}