返回介绍

14.3 工作原理

发布于 2025-02-22 14:00:45 字数 1599 浏览 0 评论 0 收藏 0

下面展示的是怎样用乘法来优化除法,其中借助了 2^n 的阶乘

enter image description here

M 是一个 magic 系数

M 的计算过程

enter image description here

因此这些代码片段通常具有这样的形式

enter image description here

n 可以是任意数,可能是 32(那么这样运算结果的高位部分从 EX 或者 RDX 寄存器中获取),可能是 31(这种情况下乘法结果的高位部分结果右移)

n 的选取是为了减少错误。

当进行有符号数除法运算,乘法结果的符号也会被放到输出结果中。

下面来看看不同之处。

#!bash
int f3_32_signed(int a)
{
    return a/3;
};
unsigned int f3_32_unsigned(unsigned int a)
{
    return a/3;
};

在无符号版本的函数中,magic 系数是 0xAAAAAAAB,乘法结果被 2^3*3 除。

在有符号版本的函数中,magic 系数是 0x55555556,乘法结果被 2^32 除。

符号来自于乘法结果:高 32 位的结果右移 31 位(将符号位放在 EAX 中最不重要的位置)。如果最后结果为负,则会设置为 1。

清单 14.4:MSVC 2012/OX

#!bash
_f3_32_unsigned     PROC
        mov     eax, -1431655765        ; aaaaaaabH
        mul     DWORD PTR _a$[esp-4]    ; unsigned multiply
        shr     edx, 1
        mov     eax, edx
        ret     0
_f3_32_unsigned ENDP

_f3_32_signed PROC
        mov     eax, 1431655766         ; 55555556H
        imul    DWORD PTR _a$[esp-4]    ; signed multiply
        mov     eax, edx
        shr     eax, 31                 ; 0000001fH
        add     eax, edx                ; add 1 if sign is negative
        ret     0
_f3_32_signed ENDP

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文