寄存器 edx::eax 中的 mul 和内存分配与 masm
mul and memory allocation in registers edx::eax with masm
我试图理解在汇编程序中使用 "mul" 操作数的逻辑(我正在使用 Visual Studio Community 和 MASM)。
为什么在 "mul ebx" 之后结果也改变了 edx,而不仅仅是 eax?
"The result(of MUL) is stored in register AX, register pair DX:AX, or register pair EDX:EAX (depending on the operand size), with the high-order bits of the product contained in register AH, DX, or EDX"。
那么位置是否取决于操作数的大小?在什么情况下?
.586
.model flat,c
.stack 100h
.data
.code
doit proc
;EAX = 0062EEF0 EBX = 7EFDE000 ECX = 0029FD00 EDX = 00000000
mov eax,8;
;EAX = 00000008
mov ebx,4
;EBX = 00000004
mov edx,23498
;EDX = 00005BCA
mul ebx
;EAX = 00000020 EDX = 00000000 ???? 4*8 =20(hexa).So, there is no
;overflow;why is edx changing too?
doit endp
end
是的,正如您所说,这取决于操作数的大小,而不是操作数的实际值。无论是否溢出,您总是会得到双倍大小的输出。 mul ebx
是 32 位,因此您在 edx:eax
中得到 64 位输出,其中 edx
可能为零。
正如 Peter Cordes 所指出的,如果您知道您将不需要结果的上半部分,"you can and should use the 2-operand or 3-operand immediate form of IMUL"。不要被符号所迷惑,引用指令集参考:"The two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the operands are signed or unsigned."
无符号乘法(MUL
指令)将总是符号扩展(好吧,零扩展,因为它是无符号的)到EDX
时传递一个 r/m32
大小的操作数,而不管 EDX
是否包含除零以外的任何内容。
这也适用于带符号的变体,IMUL
,尽管在那种情况下,如果结果为负,EDX
可能仅包含 FF
个字节。
MUL
和 IMUL
指令总是生成两倍于输入宽度的输出。所以:
- 8 位输入(一个在 AL 中)给出 16 位输出(在 AX 中)
- 16 位输入(一个在 AX 中)给出一个 32 位输出(在 DX:AX 中)
- 32 位输入(一个在 EAX 中)给出一个 64 位输出(在 EDX:EAX 中)
请注意,相关宽度始终是参数(和隐式 A 寄存器)的宽度,而不是保存任一值的最小宽度。 32 位乘以零将(缓慢地)将 EDX:EAX 设置为全零。
我试图理解在汇编程序中使用 "mul" 操作数的逻辑(我正在使用 Visual Studio Community 和 MASM)。 为什么在 "mul ebx" 之后结果也改变了 edx,而不仅仅是 eax? "The result(of MUL) is stored in register AX, register pair DX:AX, or register pair EDX:EAX (depending on the operand size), with the high-order bits of the product contained in register AH, DX, or EDX"。 那么位置是否取决于操作数的大小?在什么情况下?
.586
.model flat,c
.stack 100h
.data
.code
doit proc
;EAX = 0062EEF0 EBX = 7EFDE000 ECX = 0029FD00 EDX = 00000000
mov eax,8;
;EAX = 00000008
mov ebx,4
;EBX = 00000004
mov edx,23498
;EDX = 00005BCA
mul ebx
;EAX = 00000020 EDX = 00000000 ???? 4*8 =20(hexa).So, there is no
;overflow;why is edx changing too?
doit endp
end
是的,正如您所说,这取决于操作数的大小,而不是操作数的实际值。无论是否溢出,您总是会得到双倍大小的输出。 mul ebx
是 32 位,因此您在 edx:eax
中得到 64 位输出,其中 edx
可能为零。
正如 Peter Cordes 所指出的,如果您知道您将不需要结果的上半部分,"you can and should use the 2-operand or 3-operand immediate form of IMUL"。不要被符号所迷惑,引用指令集参考:"The two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the operands are signed or unsigned."
无符号乘法(MUL
指令)将总是符号扩展(好吧,零扩展,因为它是无符号的)到EDX
时传递一个 r/m32
大小的操作数,而不管 EDX
是否包含除零以外的任何内容。
这也适用于带符号的变体,IMUL
,尽管在那种情况下,如果结果为负,EDX
可能仅包含 FF
个字节。
MUL
和 IMUL
指令总是生成两倍于输入宽度的输出。所以:
- 8 位输入(一个在 AL 中)给出 16 位输出(在 AX 中)
- 16 位输入(一个在 AX 中)给出一个 32 位输出(在 DX:AX 中)
- 32 位输入(一个在 EAX 中)给出一个 64 位输出(在 EDX:EAX 中)
请注意,相关宽度始终是参数(和隐式 A 寄存器)的宽度,而不是保存任一值的最小宽度。 32 位乘以零将(缓慢地)将 EDX:EAX 设置为全零。