用长长的海湾合作​​委员会在x86 divdi3师 [英] divdi3 division used for long long by gcc on x86

查看:358
本文介绍了用长长的海湾合作​​委员会在x86 divdi3师的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GCC 看到乘法或未在硬件支持的整数类型划分,它生成调用特殊的库函数。

When gcc sees multiplication or division of integer types that isn't supported in hardware, it generates call to special library function.

http://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html#Integer-library-routines

据上面的链接,长__divdi3(长,长二)用于长除法。然而,在这里 http://gcc.gnu.org/onlinedocs/ GCC-3.3 / gccint /库-Calls.html divdi为呼一签双字分工解释说。当第一次源具有双后缀克利映射 - >长的参数,第二个状态divdi对于双字和udivdi全字(?单吧)

According link above, long __divdi3 (long a, long b) used for division of long. However, here http://gcc.gnu.org/onlinedocs/gcc-3.3/gccint/Library-Calls.html divdi explained as "call for division of one signed double-word". When first source has cleary mapping of di suffix -> long arguments, second states divdi for double-word and udivdi for full-word (single, right?)

当我编译简单的例子

int main(int argc, char *argv[]) {
    long long t1, t2, tr;

    t1 = 1;
    t2 = 1;
    tr = t1 / t2;

    return tr;
}

的gcc -Wall -O0 -m32 -march = i386的(GCC版本4.7.2)
dissamble显示我

with gcc -Wall -O0 -m32 -march=i386 (gcc ver. 4.7.2) dissamble shows me

    080483cc <main>:
     80483cc:       55                      push   %ebp
     80483cd:       89 e5                   mov    %esp,%ebp
     80483cf:       83 e4 f0                and    $0xfffffff0,%esp
     80483d2:       83 ec 30                sub    $0x30,%esp
     80483d5:       c7 44 24 28 01 00 00    movl   $0x1,0x28(%esp)
     80483dc:       00
     80483dd:       c7 44 24 2c 00 00 00    movl   $0x0,0x2c(%esp)
     80483e4:       00
     80483e5:       c7 44 24 20 01 00 00    movl   $0x1,0x20(%esp)
     80483ec:       00
     80483ed:       c7 44 24 24 00 00 00    movl   $0x0,0x24(%esp)
     80483f4:       00
     80483f5:       8b 44 24 20             mov    0x20(%esp),%eax
     80483f9:       8b 54 24 24             mov    0x24(%esp),%edx
     80483fd:       89 44 24 08             mov    %eax,0x8(%esp)
     8048401:       89 54 24 0c             mov    %edx,0xc(%esp)
     8048405:       8b 44 24 28             mov    0x28(%esp),%eax
     8048409:       8b 54 24 2c             mov    0x2c(%esp),%edx
     804840d:       89 04 24                mov    %eax,(%esp)
     8048410:       89 54 24 04             mov    %edx,0x4(%esp)
     8048414:       e8 17 00 00 00          call   8048430 <__divdi3>
     8048419:       89 44 24 18             mov    %eax,0x18(%esp)
     804841d:       89 54 24 1c             mov    %edx,0x1c(%esp)
     8048421:       8b 44 24 18             mov    0x18(%esp),%eax
     8048425:       c9                      leave
     8048426:       c3                      ret

请注意 8048414:拨打8048430&LT; __ divdi3&GT;

我不能用gcc的lib为我的项目,它的多平台。我希望不要写所有的 __所有平台* 功能(速度不是问题),但现在我有点糊涂了。

I can't use gcc lib for my project and it's multiplatform. I hoped not to write all __* functions for all platforms (speed is not matter), but now I'm a bit confused.

有人可以解释,为什么会出现 __ divdi3 (不是 __ divti3 )的调用产生得到long long int (64位)划分的?

Can somebody explain, why is there __divdi3 (not __divti3) call generated for long long int (64-bit) division?

推荐答案

有没有字作为字。在x86机器,文字通常是指16位。这是惯例。通常情况下,为16位或32位数字which's宽度取决于激活模式(真实或保护)。

There is not word as word. On x86 machines, word usually means 16-bits. It's customary. Normally, a word is 16-bit or 32-bit number which´s width depends on activated mode (real or protected).

我觉得这个术语已经指出由于Linux / UNIX通常在许多平台上运行。你可以感受到更多的工具,长期意义的冲突。活生生的例子是 GDB ,它使用是W 32位字和硬件 16位半字。

I think that this terminology has been stated because linux/unix is generally running on many platforms. You can feel conflicts of term meanings on more tools. Live example is gdb, which uses w for 32-bit word and hw for 16-bit "half-word".

修改
有用于彩车大小的另一个命名,但有时它也用于整数。它是:

EDIT: There is another naming used for size of floats, but sometimes it's also used for integers. It is:


  • 取值 - 单(?precision,字)四字节整数( INT )/花车(浮动

  • D - 双(precision)共八字节整数(长长)/花车(双击

  • T - 整数(长长)/花车( 10个字节长双

  • s - single (precision, word?) for four byte integers (int) / floats (float)
  • d - double (precision) for eight byte integers (long or long long) / floats (double)
  • t - ten bytes for integers (long long) / floats (long double)

此命名用于所有的算术加法,如 __ divsi3 __ divdi3 __ divti3 __ mulsi3 __ muldi3 __ MULTI3 ...(以及所有 U - 符号 - 变型)。这对 __ divdi3 的原因。完整列表是在这个页面

This naming is used for all arithmetic additions, like __divsi3, __divdi3, __divti3 or __mulsi3, __muldi3, __multi3... (and all u - unsigned - variants). That's the reason for __divdi3. Complete list is on this page.

64位数字的32位机师采用先进的(和有点难)算法。你可以使用你在学校学到的算法圣多美和普林西比。从减去大数目较小的值会浪费时间,但可以单独使用。减去不同幂零件和得到的结果更快。下面是简单的伪code它(对看看这个答案关于大整数):

Division of 64-bit numbers on 32-bit machines uses advanced (and bit difficult) algorithm. You can use algorithm principe you've learned in school. Substracting small value from big number would waste time, but you can substract parts with different exponentiation separately and get the result faster. Here's simple pseudo-code for it (have a look on this answer about big-integers):

result = 0;
count = 0;
remainder = numerator;

while(highest_bit_of_divisor_not_set) {
    divisor = divisor << 1;
    count++;
}
while(remainder != 0) {
    if(remainder >= divisor) {
        remainder = remainder - divisor;
        result = result | (1 << count);
    }
    if(count == 0) {
        break;
    }
    divisor = divisor >> 1;
    count--;
}

这篇关于用长长的海湾合作​​委员会在x86 divdi3师的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆