返回介绍

21.2 乘法,除法

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

#!cpp
#include <stdint.h>
uint64_t f3 (uint64_t a, uint64_t b)
{
        return a*b;
};
uint64_t f4 (uint64_t a, uint64_t b)
{
        return a/b;
};
uint64_t f5 (uint64_t a, uint64_t b)
{
        return a % b;
};

代码 21.3: MSVC 2012 /Ox /Ob1

#!bash
_a$ = 8                                     ; size = 8
_b$ = 16                                    ; size = 8
_f3     PROC
        push        DWORD PTR _b$[esp]
        push        DWORD PTR _b$[esp]
        push        DWORD PTR _a$[esp+8]
        push        DWORD PTR _a$[esp+8]
        call        __allmul ; long long multiplication
        ret         0
_f3     ENDP
_a$ = 8                                     ; size = 8
_b$ = 16                                    ; size = 8
_f4     PROC
        push        DWORD PTR _b$[esp]
        push        DWORD PTR _b$[esp]
        push        DWORD PTR _a$[esp+8]
        push        DWORD PTR _a$[esp+8]
        call        __aulldiv ; unsigned long long division
        ret         0
_f4     ENDP
_a$ = 8                                     ; size = 8
_b$ = 16                                    ; size = 8
_f5     PROC
        push        DWORD PTR _b$[esp]
        push        DWORD PTR _b$[esp]
        push        DWORD PTR _a$[esp+8]
        push        DWORD PTR _a$[esp+8]
        call        __aullrem ; unsigned long long remainder
        ret         0
_f5     ENDP

乘法和除法是更为复杂的操作,一般来说,编译器会嵌入库函数的 calls 来使用。

部分函数的意义:可参见附录 E。

Listing 21.4: GCC 4.8.1 -O3 -fno-inline

#!bash
_f3:
        push        ebx
        mov         edx, DWORD PTR [esp+8]
        mov         eax, DWORD PTR [esp+16]
        mov         ebx, DWORD PTR [esp+12]
        mov         ecx, DWORD PTR [esp+20]
        imul        ebx, eax
        imul        ecx, edx
        mul         edx
        add         ecx, ebx
        add         edx, ecx
        pop         ebx
        ret
_f4:
        sub         esp, 28
        mov         eax, DWORD PTR [esp+40]
        mov         edx, DWORD PTR [esp+44]
        mov         DWORD PTR [esp+8], eax
        mov         eax, DWORD PTR [esp+32]
        mov         DWORD PTR [esp+12], edx
        mov         edx, DWORD PTR [esp+36]
        mov         DWORD PTR [esp], eax
        mov         DWORD PTR [esp+4], edx
        call        ___udivdi3 ; unsigned division
        add         esp, 28
        ret
_f5:
        sub         esp, 28
        mov         eax, DWORD PTR [esp+40]
        mov         edx, DWORD PTR [esp+44]
        mov         DWORD PTR [esp+8], eax
        mov         eax, DWORD PTR [esp+32]
        mov         DWORD PTR [esp+12], edx
        mov         edx, DWORD PTR [esp+36]
        mov         DWORD PTR [esp], eax
        mov         DWORD PTR [esp+4], edx
        call        ___umoddi3 ; unsigned modulo
        add         esp, 28
        ret

GCC 的做法几乎一样,但是乘法代码内联在函数中,可认为这样更有效。

GCC 有一些不同的库函数:参见附录 D

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

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

发布评论

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