返回介绍

14.4 得到除数

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

14.4.1 变形#1

通常,代码具有这样一种形式

#!bash
mov     eax, MAGICAL CONSTANT
imul    input value
sar     edx, SHIFTING COEFFICIENT ; signed division by 2^x using arithmetic shift right
mov     eax, edx
shr     eax, 31
add     eax, edx

我们将 32 位的 magic 系数表示为 M,移位表示为 C,除数表示为 D

我们得到的除法是

enter image description here

举个例子

清单 14.5:优化模式 MSVC2012

#!bash
mov     eax, 2021161081     ; 78787879H
imul    DWORD PTR _a$[esp-4]
sar     edx, 3
mov     eax, edx
shr     eax, 31             ; 0000001fH
add     eax, edx

enter image description here

比 32 位的数字大,为了方便,于是我们使用用 Wolfram Mathematica 软件。

In[1]:=N[2^(32+3)/2021161081]
Out[1]:=17.

因此例子中的代码得到结果是 17。

对于 64 位除法来说,原理是一样的,但是应该使用 2^64 来代替 2^32。

#!bash
uint64_t f1234(uint64_t a)
{
    return a/1234;
};

清单 14.7:MSVC2012/Ox

#!bash
f1234   PROC
        mov     rax, 7653754429286296943 ; 6a37991a23aead6fH
        mul     rcx
        shr     rdx, 9
        mov     rax, rdx
        ret     0
f1234   ENDP

清单 14.8:Wolfram Mathematica

In[1]:=N[2^(64+9)/16^^6a37991a23aead6f]
Out[1]:=1234.

14.4.2 变形#2

忽略算数移位的变形也是存在的

#!bash
mov     eax, 55555556h ; 1431655766
imul    ecx
mov     eax, edx
shr     eax, 1Fh

更加简洁

enter image description here

在这个例子中

enter image description here

再用一次 Wolfram Mathematica

In[1]:=N[2^32/16^^55555556]
Out[1]:=3.

得到的除数是 3

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

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

发布评论

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