一,前言
使用64位体系结构对应用程序的开发者来说,Solaris 64位操作系统和32位操作系统之间的最大差别在于它们使用的C语言数据类型模型。64位操作系统使用LP64模型,在LP64模型中long类型和指针类型是64位的。其他基本数据类型和32位的模型一样。32位数据类型使用ILP32模型,其中的int,long和指针类型都是32位的。下面列出了64位环境的主要特点和使用时需要考虑的问题。l 巨大的虚拟地址空间在64位环境中,一个进程可以有多达64位宽的虚拟地址空间,或18 exabytes(18*260字节)。这是32位环境中4G虚拟地址空间的四十亿倍。由于硬件的限制,有的64位平台无法完全支持64位的地址空间。大地址空间使得系统可以创建更多的线程,在32位平台上一个缺省的线程需要1M堆栈,在64位平台上一个缺省的线程需要2M堆栈。在32位平台上可以创建4000个缺省线程,在64位平台上可以创建8万亿个缺省线程。l 使用核心内存的程序由于系统核心内部也使用64位的数据结构,所以现存的程序,如果使用了libkvm,/dev/mem或/dev/kmem,将无法再在64位环境中运行。必须将这样的程序转变为64位的程序。l /proc的限制一个使用/proc的32位应用程序可以访问32位进程的属性,但无法访问一个64位进程的属性;现存的描述进程的接口和数据结构不能包含所涉及的64位的量。这种程序必须重新编译成64位应用程序,这样才能访问32位和64位进程的属性。l 64位库32位的应用程序必须和32位的库链接在一起,64位的应用程序必须和64位的库链接在一起。除了过时的库,所有的库都有32位和64位两种版本。但没有一个64位库是静态链接库。l 64位运算尽管在32位的Solaris系统中已经有64位运算了,但64位的实现为整数操作和参数传递提供了完全64位的机器寄存器。l 大文件如果一个程序只需要支持大文件,使用32位Solaris的大文件接口就可以了。但是为了充分的利用64位的优点,最好把程序转变为64位代码。
64 位计算
Red Hat 和很多其它发行商为 Compaq/DEC Alpha 提供了一种 64 位版的 Linux。您可以在 AlphaLinux Web 站点上了解关于这种 Linux 的其它信息。64 位的 Solaris 和 64 位的 Linux/Alpha 都使用 LP64 数据模型,它能够带来很好的兼容性。
不久,Intel Itanium(TM) IA-64 处理器也能使用一种 64 位版的 Linux。您可以在 IA-64 Linux Project Web 站点了解关于这种 Linux 的更多信息。一种支持 IBM 64 位 PowerPC 体系结构的 Linux 也在开发之中。
请注意,尽管 SuSE Linux/UltraSPARC 的内核运行在 64 位的模式中,但 SuSE Linux/UltraSPARC 目前并不支持 64 位的用户空间应用程序。
二,对于hp 32bit位 和64bit的区别
hp C/HP-UX 32-bit and 64-bit base data types
data type
ILP32 size (bits)
LP64 size (bits)
char
8
8
short
16
16
int
32
32
long
32
64
long long (1)
64
64
pointer
32
64
float
32
32
double
64
64
long double
128
128
enum (2)
32
32
最主要的区别是long型和pointer型数据。
三,32bit机数据在内容中的说明
A) 在为变量/对象分配内存的时候,总是以4字节对齐,无论你的变量类型是什么。也就是说,任何一个变量/对象的存储空间都是以4的整数倍的地址开始的。
B) 对于pointer型数据,因为内容是地址,要求该地址也必须是4整数倍。
C) 例如:
main()
{
struct student
{
int i;
long l;
}node;
struct student *p;
p=&node;
int *pp;
char *qq;
long *ll;
p->i=1;
p->l=2;
pp=(int *)p;
qq=(char *)p;
ll=(long *)p;
printf("int pp l=%d\n",*(pp+1)); /*result =2*/
printf("char qq l=%d\n",*(qq+7)); /*result =2*/
(char型指针指向的内容只能是1字节的数据。如果将
p->l赋更大的值22222,*(qq+7))只能取到地址为0x200000007ffff657
对应的内容)
printf("long ll l=%d\n",*(ll+1)); /*result =2*/
}
结构体的内存分配如下:
0x200000007ffff650: 0x00000001 0x00000002 0x00000000 0x00000000
0x200000007ffff660: 0x00000190 0x000002ec 0x000017a0 0x00000002
0x200000007ffff670: 0x00000000 0x00000000
图解如下:
pp,qq,ll
Adress
data
0x200000007ffff650
00
0x200000007ffff651
00
0x200000007ffff652
00
0x200000007ffff653
01
0x200000007ffff654
l
00
0x200000007ffff655
00
0x200000007ffff656
00
0x200000007ffff657
02
0x200000007ffff658
0x200000007ffff659
0x200000007ffff65A
i
四,64bit机数据在内容中的说明
A) 在为变量/对象分配内存的时候,总是以8字节对齐,无论你的变量类型是什么。也就是说,任何一个变量/对象的存储空间都是以8的整数倍的地址开始的。
B) 对于pointer型数据,因为内容是地址,要求该地址也必须是8整数倍。
C) 例如:
main()
{
struct student
{
int i; /*8个字节的存储空间,*/
long l; /*8个字节的存储空间,*/
}node;
struct student *p;
p=&node;
int *pp;
char *qq;
long *ll;
p->i=1;
p->l=222222222;
pp=(int *)p;
qq=(char *)p;
ll=(long *)p;
printf("int pp l=%d\n",*(pp+2));/*result int pp l=222222222*/
printf("char qq l=%d\n",*(qq+15));/*result int pp 13*/
printf("long ll l=%d\n",*(ll+1));/*result int pp l=222222222*/
}
五,64bit机下,内存对齐的例子
正确:
int main()
{
long i;
char a[44];
long *p;
p=(char *)(a+8);
*p=3;
printf("*p=%d\n",*p); /*result = 3*/
}
错误:
void main()
{
long i;
char a[44];
long *p;
p=a+4;
*p=3;
printf("*p=%d\n",*p); /*bus error*/
}
六,程序中的内存分配浅谈
一.存空间的对齐规则
首先看一段例子:
……
int i1;
char c1;
char c2;
int i2;
cout << "i1:" <<&i1 << "\n";
cout << "c1:" <<(void *)&c1 << "\n";
cout << "c2:" <<(void *)&c2 << "\n";
cout << "i2:" <<&i2 << "\n";
……
输出结果如下:
i1:0012FF4C
c1:0012FF48
c2:0012FF44
i2:0012FF40
是不是有些奇怪?
我们知道char类型的变量是只占用一个字节的,用sizeof(char)得到的结果也会是1。但在这里我们看到,c1和c2都被分配了4个字节的存储空间,在32bit机下,在为变量/对象分配内存的时候,总是以4字节对齐,无论你的变量类型是什么。也就是说,任何一个变量/对象的存储空间都是以4的整数倍的地址开始的。64bit机下,都是8的倍数。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jiantiantian/archive/2008/12/17/3540923.aspx