理解 IMUL 指令定义的溢出标志 (OF) 时遇到的问题

dum*_*unt 1 x86 assembly eflags

我对为什么在以下说明中imul设置感到困惑OF

mov  al, 48
mov  bl, 4
imul bl      ; AX = 00C0h, OF = 1
Run Code Online (Sandbox Code Playgroud)

不在以下说明中

mov  ax, 48
mov  bx, 4
imul bx      ; DX:AX = 000000C0h, OF = 0
Run Code Online (Sandbox Code Playgroud)

Nat*_*dge 6

IMUL当结果的低半部分(解释为适当大小的有符号整数)不等于两个输入数字相乘的数学结果时,设置溢出标志。

48乘以4的数学结果是192。之后留在AL中的imul bl值为C0h。作为有符号 8 位整数,表示数字 -64。从数学上来说,192和-64不是同一个数,所以必须设置溢出。

之后imul bx,AX 中剩下的值为00C0h。作为一个带符号的 16 位整数,表示数字 192。因此未设置溢出标志。

同样,如果对低半部分进行符号扩展将产生与完整乘积不同的值,则设置溢出标志。当您将 8 位值符号扩展C0h为 16 位时,您会得到FFC0h,它不等于00C0h,因此设置了溢出。当您将 16 位值符号扩展00C0h到 32 位时,您会得到000000C0h,它确实等于实际的 32 位结果,因此不会设置溢出。

同样,只有当结果的高半部分的每一位都等于低半部分的符号位时,溢出标志才会被清除。8 位值的符号位C0h为 1,但高半部分不是 FFh,而是 00h,因此设置了溢出。16 位值的符号位00C0h为 0,高半位为0000h,因此溢出被清除。

  • TL:DR: `OF` 告诉您是否可以将双宽度完整结果截断回输入宽度而不更改其值。如果您使用“imul”或“mul”作为其他 8 位或 16 位操作(例如“add”)序列的一部分,*不*计划使用结果的高半部分,这就是您想知道的内容(或者有一个较慢的版本。) (2认同)