带 masm 的寄存器 edx::eax 中的 mul 和内存分配

Posted

技术标签:

【中文标题】带 masm 的寄存器 edx::eax 中的 mul 和内存分配【英文标题】:mul and memory allocation in registers edx::eax with masm 【发布时间】:2016-12-07 16:14:02 【问题描述】:

我试图了解在汇编程序中使用“mul”操作数的逻辑(我正在使用 Visual Studio Community 和 MASM)。 为什么,在“mul ebx”之后结果也在改变edx,而不仅仅是eax? “MUL 的结果存储在寄存器 AX、寄存器对 DX:AX 或寄存器对 EDX:EAX 中(取决于操作数大小),乘积的高位包含在寄存器 AH、DX 或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 

【问题讨论】:

目的地不同的原因是涉及的位数,两个8位操作数需要16位结果,所以16位寄存器AX,16位x 16位需要32位结果,所以DX:AX 的 32 位,32 位 x 32 位的结果需要 64 位,因此 EDX:EAX 中的 64 位 您可以将mul r/m8 视为在 AH:AL 中产生一对低/高输出。但是,如果您不需要结果的高半部分,您可以并且应该使用 IMUL 的 2-operand 或 3-operand-immediate 形式。 EDX 发生了变化,因为没有涉及溢出概念。这些位是结果的一部分,即使你做了零次零 【参考方案1】:

是的,正如您所说,它取决于操作数大小,这不是操作数的实际值。你总是得到双倍大小的输出,溢出与否。 mul ebx 是 32 位,因此您在 edx:eax 中获得 64 位输出,其中 edx 可能为零。

正如 Peter Cordes 所指出的,如果您知道不需要结果的上半部分,“您可以而且应该使用 IMUL 的 2 操作数或 3 操作数立即数形式”。不要被有符号所迷惑,引用指令集参考:“二操作数和三操作数形式也可以与无符号操作数一起使用,因为无论操作数是否是,乘积的下半部分都是相同的签名或未签名。”

【讨论】:

【参考方案2】:

MULIMUL 指令始终生成两倍于输入宽度的输出。所以:

8 位输入(AL 中的一个)提供 16 位输出(AX 中) 16 位输入(AX 中的一个)提供 32 位输出(DX:AX 中) 32 位输入(EAX 中的一个)提供 64 位输出(EDX:EAX 中)

请注意,相关宽度始终是参数(以及隐式 A 寄存器)的宽度,而不是保存任何一个值的最小宽度。 32 位乘以零将(缓慢地)将 EDX:EAX 设置为全零。

【讨论】:

使用 16 位输入(AX 中的一个),32 位输出将在 DX:AX 而不是 EAX 中。 哦!当然。 16 位 MUL 早于 EAX,一旦引入 EAX,再改变 MUL 为时已晚。谢谢!【参考方案3】:

无符号乘法(MUL 指令)总是在传递r/m32 大小的操作数时将符号扩展(嗯,零扩展,因为它是无符号的)到EDX ,无论EDX 是否包含除零以外的任何内容。

这也适用于带符号的变体IMUL,但在这种情况下,如果结果为负,EDX 可能只包含FF 字节。

【讨论】:

术语:它不是 EDX 的符号或零扩展。它是结果的上半部分,可能是也可能不是下半部分的零扩展,具体取决于结果的大小。

以上是关于带 masm 的寄存器 edx::eax 中的 mul 和内存分配的主要内容,如果未能解决你的问题,请参考以下文章

汇编程序如何处理在 2 个寄存器上分隔的值(例如 EDX:EAX)?

我如何获得负股息的正模数

把汇编代码转化成C代码

2017-2018-1 20179219《Linux内核原理与分析》第二周作业

寄存器周围的括号是啥意思? [复制]

算术和逻辑操作