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
}
我对 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
}