32位寄存器乘法中的标记OF

Tag OF in 32 bit register multiplication

我对 Assembly 中的产品有疑问。我想将两个矩阵相乘,例如,1raw x 1column。 如果结果大于 2^15 IMUL 设置标志 OF=1 因为溢出,但我不明白为什么,事实上我使用的是 32 位寄存器而不是 16 位。下面是一些代码来解释这个问题,例如:

short int mat1[] = {-70};
short int mat2[] = {20000};

__asm {
        lea eax, mat1
        lea ebx, mat2
        xor edx, edx
        xor ecx, ecx
        movsx esi, [eax][ecx*2]  //esi = 70
        imul esi, [ebx][edx*2]   //multiplicates esi for mat2 that is 20000
}

现在esi是0022A340h而不是FFFFFDDD20h(-140000),而且标志OF=1,为什么?结果与数字而不是矩阵相同,但我正在使用它们并且我不确定它是否无关紧要,所以我在这个例子中发布了 mat1 和 mat2。

您还应该对第二个操作数进行符号扩展:

short int mat1[] = {-70};
short int mat2[] = {20000};

__asm {
        lea eax, mat1
        lea ebx, mat2
        xor edx, edx
        xor ecx, ecx
        movsx esi, WORD PTR[eax][ecx*2]  //esi = 70
        movsx edi, WORD PTR[ebx][edx*2] 
        imul esi, edi
}

或者只做 16 位乘法(将 return 32 位结果 dx:ax)

__asm {
        lea esi, mat1
        lea edi, mat2
        xor edx, edx
        xor ecx, ecx
        mov ax, [esi][ecx*2]  //esi = 70
        imul WORD PTR[edi][edx*2] 
        // result is now in dx:ax
}