当gcc
看到硬件不支持的整数类型的乘法或除法时,它会生成对特殊库函数的调用。
http://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html#Integer-library-routines
根据上面的链接,long __divdi3 (long a, long b)
用于划分长。然而,这里http://gcc.gnu.org/onlinedocs/gcc-3.3/gccint/Library-Calls.html divdi解释为“要求划分一个签名的双字”。当第一个源具有di后缀 - >长参数的清晰映射时,第二个状态为双字的divdi和全字的udivdi(单个,右?)
当我编译简单的例子
int main(int argc, char *argv[]) {
long long t1, t2, tr;
t1 = 1;
t2 = 1;
tr = t1 / t2;
return tr;
}
与qazxsw poi(gcc ver.4.7.2)反汇编向我展示
gcc -Wall -O0 -m32 -march=i386
注意 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
。
我不能将gcc lib用于我的项目,而且它是多平台的。我希望不要为所有平台编写所有8048414: call 8048430 <__divdi3>
函数(速度无关紧要),但现在我有点困惑。
有人可以解释一下,为什么__*
(不是__divdi3
)调用为__divti3
(64位)分区生成?
在x86机器上,术语“字”通常意味着存在16位值。更普遍地说,在计算机科学领域,long long int
可以表示几乎任意长度的值,在嵌入式系统中10或12位的单词并不罕见。
我相信你所使用的术语仅用于Linux / Unix系统,只是为了统一操作系统,而与构建的目标平台无关。在word
中可以找到使用相同符号的示例,它使用gdb
作为32位字,w
使用16位“半字”(在x86意义上)。
此外,该约定还可以轻松扩展到标准IEEE-754浮点数,并在下面的几个要点中进行了总结
hw
- 单个(精度,字)用于四个字节的整数(s
)/浮点数(int
)float
- 八个字节整数的双精度(精度)(d
或long
)/浮点数(long long
)double
- 十个字节的整数(t
)/浮点数(long long
)这个命名约定用于所有算术内置函数,如long double
,__divsi3
,__divdi3
或__divti3
,__mulsi3
,__muldi3
...(以及所有__multi3
- unsigned - variants)。完整列表可以找到u
。
在32位机器上划分64位数字使用高级(和难点)算法。但是,您仍然可以使用您在学校学到的算法原理。这是一个简单的伪代码(看看关于大整数的here):
this answer