内存对齐
c++ 内存对齐规则

c++ 内存对齐规则
C++中的内存对齐规则确保数据结构在内存中按照特定的规则进行布局,以便提高访问效率和系统性能。
下面是关于C++内存对齐的详细介绍:
一、内存对齐原则:
1.对于任何给定的数据类型,其起始地址必须是它自身大小的整数倍。
2.结构体的总大小必须是其最大成员大小的整数倍。
二、默认对齐:
1.基本数据类型(如char、int、float等)的默认对齐值通常等于其大小。
2.对于结构体,其默认对齐值等于其最大成员大小。
三、结构体对齐规则:
1.结构体的对齐值为结构体中最大成员的大小。
2.结构体的大小为结构体中所有成员大小的总和,但不会小于其对齐值。
3.如果结构体中包含成员的自定义对齐指令(如#pragma pack),则按照指令指定的对齐方式进行对齐。
四、对齐修饰符:
1.C++11引入了对齐修饰符alignas,可以用于指定特定变量或结构体的对齐方式。
2.例如:alignas(8) int array[16];将array数组的对齐方式设置为8字节。
五、注意事项:
1.内存对齐可以提高访问效率,但可能会浪费一些内存空间。
2.对于跨平台开发,需要注意不同平台上的对齐规则可能不同,因此在进行数据传输或持久化存储时需要考虑跨平台兼容性。
总之,C++的内存对齐规则确保了数据在内存中按照特定规则进行布局,以提高访问效率和系统性能。
开发者可以使用默认对齐规则或使用对齐修饰符来指定特定变量或结构体的对齐方式。
四字节

|--------int--------| 4字节
|char|----|--short-| 4字节
总共占8字节
3.test3
?
typedef struct node2
{
char a;
int b;
short c;
}S2;
则siezof(S3)=12.最长数据类型为int,占4个字节。因此以4字节对齐,其在内存空间存放方式如下:
short b;
static int c;
}S3;
则sizeof(S3)=8.这里结构体中包含静态数据成员,而静态数据成员的存放位置与结构体实例的存储地址无关(注意只有在C++中结构体中才能含有静态数据成员,而C中结构体中是不允许含有静态数据成员的)。其在内存中存储方式如下:
同理,分析上面例子C:
#pragma pack (2) /*指定按2字节对齐*/
struct C {
char b;
int a;
short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
第 一个变量b的自身对齐值为1,指定对齐值为2,所以,其有效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x0000%1= 0;第二个变量,自身对齐值为4,指定对齐值为2,所以有效对齐值为2,所以顺序存放在0x0002、0x0003、0x0004、0x0005四个连续 字节中,符合0x0002%2=0。第三个变量c的自身对齐值为2,所以有效对齐值为2,顺序存放
例子分析:
分析例子B;
struct B {
char b;
ARM处理器下的内存对齐问题

ARM处理器下的内存对齐问题介绍内存访问可以分为aligned和未对齐unaligned.对齐内存访问发生在数据分配在natural size boundary,如果这个数据的大小是4 bytes,而且它分配的地址可以被4整除,它就是分配在natural size boundary的,它就是内存对齐的.未对齐内存访问就是其他的所有情况(内存地址不能被4整除);ARM处理器被设计成可以高效的访问对齐数据,在ARM处理器上尝试访问未对齐内存数据将得到两种结果:错误数据或显著的执行差异(很快会讨论这些不同的表现).这不同于其他的CISC类型的处理器,它们可以正常的访问未对齐数据.这篇文档将会描述一些对应用程序来说通用的方式处理未对齐内存访问和提供一些推荐的解决方案以解决这些问题.症状上述问题针对所有ARM架构的.然而,根据MMU是否使能和操作系统的支持,应用程序在不同的平台上有不同的表现.在默认情况下,未对齐内存访问不会被捕捉,而是返回一个错误数据.在使能了MMU的平台上,OS将可以捕捉未对齐内存访问而且在运行时调整正确.返回的结果将是正确的数据,但是将花费 10-20个cpu周期.通常原因类型分配Code:void my_func(char *a){int *b = (int *)a;DBGPRINTF("%d", *b);}这个简单的例子可以生成未对齐内存访问,因为我们不能保证参数char* a是在4字节边界上的.这样的类型定义在任何时候都应该避免.使用数据buffer大多数常见的未对齐内存访问发生在错误的处理数据buffer,这些数据buffer可能包含任何从usb端口,网路,或文件中读取的数据.通常会设置这些数据为packed,意味着没有padding嵌入以确保buffer中的数据是natural size boundary的.在这个例子中,我们将讨论装载从一个文件一个windows BMP格式数据,然后解析其文件头的情况.一个windows BMP文件包含一个以下数据项的文件头,文件头由两个结构体组成:Code:typedef PACKED struct{unsigned short int type;unsigned int size;unsigned short int reserved1, reserved2;unsigned int offset;} HEADER;typedef PACKED struct{unsigned int size;int width,height;unsigned short int planes;unsigned short int bits;unsigned int compression;unsigned int imagesize;int xresolution,yresolution;unsigned int ncolours;unsigned int importantcolours;} INFOHEADER;注意HEADER和INFOHEADER结构体的大小分别是14和40字节.假设我们想在程序运行是检测图片的宽带和高度,得到这些数据的代码如下:Code:#define INFOHEADER_OFFSET (sizeof(HEADER))#define WIDTH_OFFSET (INFOHEADER_OFFSET + offsetof(INFOHEADER, width))#define HEIGHT_OFFSET (INFOHEADER_OFFSET + offsetof(INFOHEADER, height))int imageWidth, imageHeight;void * fileBuf;pMe->mFile = IFILEMGR_OpenFile(pMe->mFileMgr, "test.bmp", _OFM_READ);if (pMe->mFile){IFILE_GetInfo(pMe->mFile, &fileInfo);fileBuf = MALLOC(fileInfo.dwSize);if (fileBuf){result = IFILE_Read(pMe->mFile, fileBuf, fileInfo.dwSize);if (result == fileInfo.dwSize){imageWidth = *((uint32*)(((byte*)fileBuf) + WIDTH_OFFSET));imageHeight = *((uint32*)(((byte*)fileBuf) + HEIGHT_OFFSET));}}}注意宽度和高度的偏移.因为它们位于一个half-word boundary,以上面的代码访问它们的值将是未对齐内存访问.一些推荐的方式解决这个问题如下:推荐方案使用memcpy我们第一个选择是简单的使用memcpy将数据从buffer处理到我们的局部变量中:Code:if (result == fileInfo.dwSize){MEMCPY(&imageWidth,(((byte*)fileBuf)+WIDTH_OFFSET),sizeof(uint32));MEMCPY(&imageHeight,(((byte*)fileBuf)+HEIGHT_OFFSET),sizeof(uint32));}结果是内存被紧密的拷贝,避免了对齐问题.使用PACKED编译指令或者,我们可以使用PACKED编译指令以允许使用指针直接的访问我们想要的数据.也就是强制编译器处理对齐问题.在BREW环境下,PACKED定义如下:Code:#ifdef __ARMCC_VERSION#define PACKED __packed#else#define PACKED#endif通过标明一个指针是PACKED的,ARM编译器将始终生成合适的指令可以正确的访问内存.不管对齐,上边的例子的一个修改的版本,使用PACKED的指针,如下:Code:#define INFOHEADER_OFFSET (sizeof(HEADER))#define WIDTH_OFFSET (INFOHEADER_OFFSET + offsetof(INFOHEADER, width))#define HEIGHT_OFFSET (INFOHEADER_OFFSET + offsetof(INFOHEADER, height))PACKED uint32 * pImageWidth;PACKED uint32 * pImageHeight;uint32 imageWidth, imageHeight;void * fileBuf;pMe->mFile = IFILEMGR_OpenFile(pMe->mFileMgr, "test.bmp", _OFM_READ);if (pMe->mFile){IFILE_GetInfo(pMe->mFile, &fileInfo);fileBuf = MALLOC(fileInfo.dwSize);if (fileBuf){result = IFILE_Read(pMe->mFile, fileBuf, fileInfo.dwSize);if (result == fileInfo.dwSize){pImageWidth = (uint32*)(((byte*)fileBuf) + WIDTH_OFFSET);pImageHeight = (uint32*)(((byte*)fileBuf) + HEIGHT_OFFSET);imageWidth = *pImageWidth;imageHeight = *pImageHeight;}}}定义Well-Aligned数据结构虽然我们一般不能控制定制的数据格式,比如上面例子中的BMP文件头,但是,当我们定义自己的数据结构我们可以将数据设计成Well-Aligned方式.以下例子演示这种方式:Code:#ifdef __ARMCC_VERSIONtypedef PACKED struct{short a; // offsetof(a) = 0int b; // offsetof(b) = 2 ?misalignment problem!short c; // offsetof(c) = 6} BAD_STRUCT;typedef struct{int b; // offsetof(b) = 0 ?no problem!short a; // offsetof(a) = 4short c; // offsetof(c) = 6} GOOD_STRUCT;简单的重新定义结构提成员的顺序,我们可以解决一些对齐问题.同时注意如果BAD_STRUCT没有定义为PACKED,编译器一般将会插入padding以使每个成员是Well-Aligned的.然而,这通常是不可取的,因为它浪费内存,而且几乎总是可以通过按顺序声明减少大小而避免。
计算机内存对齐原理

计算机内存对齐原理计算机内存对齐原理是指在计算机系统中,为了提高效率和正确性,数据在内存中的存储会被按照一定的规则进行排列。
这一原理涉及到了计算机硬件和软件的多个层面。
1. **数据对齐(Data Alignment)**:数据对齐是指数据在内存中的存放位置是按照一定的边界进行的。
比如,在许多计算机体系结构中,数据通常按照4字节或8字节的边界对齐。
这意味着数据的地址通常是这些边界数的倍数。
这样做的目的是为了提高数据访问的效率,因为非对齐的访问通常需要额外的硬件指令来处理,这会增加访问时间。
2. **内存访问效率**:当数据在内存中正确对齐时,处理器可以更高效地访问这些数据。
例如,如果处理器一次可以读取4字节,那么它最好是从一个4字节的边界开始访问,这样一次就能读取到整个数据块,而不需要分多次读取。
3. **指令集架构(ISA)的规定**:不同的处理器架构有不同的内存对齐要求。
例如,x86架构就有严格的数据对齐要求,而ARM架构则相对宽松。
软件开发者在编写程序时需要遵循目标处理器的ISA规定。
4. **编译器和操作系统的作用**:现代编译器和操作系统会自动处理内存对齐,以确保数据按照最佳方式存储。
它们会根据目标处理器的特点来优化代码,包括数据的内存布局。
5. **性能考量**:虽然内存对齐可以提高性能,但它也可能增加内存的使用量。
因为为了对齐数据,可能需要在数据前后填充一些无用的字节,这被称为填充(Padding)。
因此,在设计数据结构时,开发者需要在性能和内存使用之间做出权衡。
内存对齐是计算机体系结构中的一个重要概念,它影响着程序的性能和效率。
程序员在编写代码时应当了解并遵循内存对齐的原则,以优化程序的运行速度。
同时,内存对齐也是操作系统和编译器优化代码的一个重要方面。
如何通过内存对齐提高程序性能

内存对齐是一种优化程序性能的重要手段。
它可以使得数据在内存中的存储更加紧凑和高效,减少内存访问的次数和开销,从而提高程序的运行速度。
本文将从什么是内存对齐、为何需要内存对齐以及如何通过内存对齐提高程序性能等方面展开论述。
一、什么是内存对齐内存对齐是指内存中的数据在存储时按照一定的规则对齐,如按字节对齐、按字对齐等。
在现代计算机中,数据访问通常以字节为单位进行,而内存对齐能够使得数据的存储地址整除数据类型的大小。
例如,一个int类型的变量通常占用4个字节,内存对齐能够保证它存储的地址是4的倍数,而不是随机的地址。
二、为何需要内存对齐内存对齐的主要目的是提高数据存取的效率。
当数据按照字节对齐存储时,CPU在访问内存时无需额外的计算和操作,可以直接通过内存地址来获取数据,加快访问速度。
相反,如果数据没有对齐存储,CPU就需要进行额外的位移和掩码操作,这会造成额外的时间和开销。
三、内存对齐的原则1. 基本类型的变量,如int、float,通常按照其本身的大小进行对齐。
例如,一个int类型的变量通常按照4字节对齐存储。
2. 结构体的对齐规则通常是按照最大成员的大小进行对齐。
例如,一个结构体中最大的成员是8字节的double类型变量,那么结构体就按照8字节对齐存储。
3. 编译器一般会对结构体进行填充,以满足对齐的要求。
这样可以使得结构体的大小是对齐大小的整数倍,从而提高内存访问的效率。
4. 对于特殊情况和对齐要求更高的场景,可以使用编译器提供的对齐指令来自定义对齐规则。
四、如何通过内存对齐提高程序性能1. 减少内存访问次数:由于内存对齐可以使得数据在内存中的存储更加紧凑,减少了数据的分散存储,从而可以减少内存访问的次数。
对于大型数据结构或数组,内存对齐能够显著提升对内存的访问效率,加快程序的运行速度。
2. 提高缓存命中率:CPU的高速缓存是一个重要的性能瓶颈,内存对齐可以提高缓存命中率。
当数据按照对齐规则存储时,缓存可以更好地预取和预存储数据,减少了对主存的访问次数,从而提高程序的运行效率。
c语言内存对齐系数

c语言内存对齐系数C语言内存对齐系数在C语言中,内存对齐是指将结构体或联合体的成员按照一定的规则进行排列,以便于提高程序的运行效率。
内存对齐系数是用来描述对齐规则的一个参数,它决定了结构体或联合体成员在内存中的对齐方式。
1. 什么是内存对齐系数内存对齐系数是一个整数,表示结构体或联合体成员在内存中的对齐方式。
通常情况下,内存对齐系数是编译器根据目标平台的特点自动确定的,但也可以通过编译器的特殊选项来手动指定。
内存对齐系数越大,成员在内存中的对齐方式越严格。
2. 为什么需要内存对齐内存对齐是为了提高程序的运行效率和访问速度。
当结构体或联合体中的成员按照对齐规则排列时,可以减少内存访问的次数,提高内存读写效率。
此外,一些特殊的硬件平台对于数据的对齐要求非常严格,不满足对齐要求的数据可能导致硬件异常或错误。
3. 内存对齐的规则内存对齐规则是由编译器根据目标平台的特点制定的。
通常情况下,对齐规则遵循以下几个原则:- 结构体或联合体的首地址必须是其最宽基本类型成员大小的整数倍。
- 结构体或联合体的每个成员相对于结构体或联合体首地址的偏移量必须是该成员大小的整数倍。
- 结构体或联合体的总大小必须是其最宽基本类型成员大小的整数倍。
4. 内存对齐的影响内存对齐会影响程序的内存占用和性能。
由于对齐规则的存在,结构体或联合体的大小可能会比成员大小的总和要大,这会增加程序的内存占用。
但是,内存对齐可以提高内存访问的效率,尤其是对于大量的结构体或联合体访问操作,可以明显提高程序的性能。
5. 如何控制内存对齐可以通过编译器的特殊选项来手动控制内存对齐。
例如,在GCC编译器中,可以使用#pragma pack(n)来设置内存对齐系数为n。
其中,n可以是1、2、4、8等整数,表示对齐系数为1字节、2字节、4字节、8字节等。
需要注意的是,手动设置内存对齐系数可能会影响程序的性能和可移植性,应谨慎使用。
6. 示例下面以一个示例来说明内存对齐的作用。
256字节对齐计算公式

256字节对齐计算公式1.引言在计算机领域,内存对齐是一种重要的概念,它与数据在内存中的存放方式密切相关。
其中,256字节对齐是一种常见的对齐方式。
本文将介绍256字节对齐的计算公式,帮助读者更好地理解和应用该对齐方式。
2.什么是内存对齐内存对齐是指变量在内存中存放时按照一定的规则对其进行排列的过程。
由于计算机硬件读取数据的机制,对齐可以提高数据的读取效率。
对齐通常以字节为单位进行,比如4字节对齐、8字节对齐等。
3.为什么选择256字节对齐在某些应用场景下,特别是在嵌入式系统或高性能计算中,选择256字节对齐可以获得更好的性能。
这是因为256字节对齐可以最大限度地利用计算机硬件的特性,提高数据的读取和处理效率。
4. 256字节对齐计算公式假设需要存放的变量为V(以字节为单位),256字节对齐的计算公式如下:A l ig ne dA dd re ss=((V+255)/256)*256其中,A li gn ed Ad dr e ss表示对齐后的起始地址。
5.举例说明为了更好地理解256字节对齐计算公式,我们来看一个具体的例子。
假设有一个结构体需要存放在内存中,其成员变量分别为:i n ta;c ha rb;d ou ble c;这三个变量的字节大小分别为4、1和8字节。
编译器为了对齐考虑,会按照最大字节大小的变量进行对齐,即8字节对齐。
首先,计算出结构体在内存中的大小:4+1+8=13字节。
然后,按照256字节对齐计算公式进行计算:A l ig ne dA dd re ss=((13+255)/256)*256=512即结构体在内存中的起始地址为512字节。
6.总结256字节对齐是一种常见的内存对齐方式,可以提高数据在内存中的读取和处理效率。
本文介绍了256字节对齐的计算公式,并通过一个具体的例子进行了说明。
希望读者通过本文的介绍,对256字节对齐有更深入的理解,并能在实际的项目中合理应用。
内存对齐规则

内存对齐规则内存对齐是计算机系统中的一个重要概念,它指的是在内存中存储数据时,数据在内存中的起始地址必须是特定值的倍数。
这个特定值称为对齐单位。
内存对齐的存在是为了提高计算机系统的性能和效率。
本文将介绍内存对齐的规则和作用,并探讨其在计算机系统中的重要性。
一、内存对齐的规则在计算机系统中,内存对齐遵循以下规则:1. 基本对齐规则:数据的起始地址必须是其数据类型的整数倍。
例如,一个整型变量的起始地址必须是4的倍数,一个双精度浮点型变量的起始地址必须是8的倍数。
2. 结构体对齐规则:结构体中的成员变量按照其数据类型的对齐方式进行对齐。
结构体的起始地址必须是其成员变量中对齐要求最高的数据类型的整数倍。
3. 数组对齐规则:数组的起始地址必须是数组元素类型的对齐要求最高的数据类型的整数倍。
4. 结构体嵌套对齐规则:结构体嵌套时,内层结构体的起始地址必须是外层结构体中对齐要求最高的数据类型的整数倍。
二、内存对齐的作用内存对齐的主要作用是提高计算机系统的性能和效率。
具体而言,内存对齐可以带来以下好处:1. 提高访问速度:对齐的数据可以直接从内存中读取,而不需要进行额外的对齐操作。
这样可以减少内存访问的时间,提高程序的执行效率。
2. 节省内存空间:内存对齐可以使数据在内存中的布局更加紧凑,减少内存碎片的产生。
这样可以节省内存空间,提高内存的利用率。
3. 硬件兼容性:不同的硬件平台对内存对齐的要求可能不同。
遵循内存对齐规则可以增加程序在不同硬件平台上的兼容性,减少因为内存对齐问题而导致的程序错误。
三、内存对齐的重要性内存对齐在计算机系统中具有重要的意义。
首先,内存对齐可以提高程序的执行效率,减少内存访问的时间,提高计算机系统的性能。
其次,内存对齐可以减少内存碎片的产生,节省内存空间,提高内存的利用率。
此外,遵循内存对齐规则可以增加程序在不同硬件平台上的兼容性,提高程序的可移植性。
总结起来,内存对齐是计算机系统中的一个重要概念,它可以提高计算机系统的性能和效率。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言内存对齐
分类:C/C++2012-04-05 20:54 1070人阅读评论(1) 收藏举报语言c编译器平台oo
首先由一个程序引入话题:
1//环境:vc6 + windows sp2
2//程序1
3 #include <iostream>
4
5using namespace std;
6
7struct st1
8 {
9char a ;
10int b ;
11short c ;
12 };
13
14struct st2
15 {
16short c ;
17char a ;
18int b ;
19 };
20
21int main()
22 {
23 cout<<"sizeof(st1) is "<<sizeof(st1)<<endl;
24 cout<<"sizeof(st2) is "<<sizeof(st2)<<endl;
25return 0 ;
26 }
27
程序的输出结果为:
sizeof(st1) is 12
sizeof(st2) is 8
问题出来了,这两个一样的结构体,为什么sizeof的时候大小不一样呢?
本文的主要目的就是解释明白这一问题。
内存对齐,正是因为内存对齐的影响,导致结果不同。
对于大多数的程序员来说,内存对齐基本上是透明的,这是编译器该干的活,编译器为程序中的每个数据单元安排在合适的位置上,从而导致了相同的变量,不同声明顺序的结构体大小的不同。
那么编译器为什么要进行内存对齐呢?程序1中结构体按常理来理解sizeof(st1)和sizeof(st2)结果都应该是7,4(int) + 2(short) + 1(char) = 7 。
经过内存对齐后,结构体的空间反而增大了。
在解释内存对齐的作用前,先来看下内存对齐的规则:
1、对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。
2、在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
#pragma pack(n) 表示设置为n字节对齐。
VC6默认8字节对齐
以程序1为例解释对齐的规则:
St1 :char占一个字节,起始偏移为0 ,int 占4个字节,min(#pragmapack()指定的数,这个数据成员的自身长度) = 4(VC6默认8字节对齐),所以int按4字节对齐,起始偏移必须为4的倍数,所以起始偏移为4,在char后编译器会添加3个字节的额外字节,不存放任意数据。
short占2个字节,按2字节对齐,起始偏移为8,正好是2的倍数,无须添加额外字节。
到此规则1的数据成员对齐结束,此时的内存状态为:
oxxx|oooo|oo
0123 4567 89 (地址)
(x表示额外添加的字节)
共占10个字节。
还要继续进行结构本身的对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行,st1结构中最大数据成员长度为int,占4字节,而默认的#pragma pack 指定的值为8,所以结果本身按照4字节对齐,结构总大小必须为4的倍数,需添加2个额外字节使结构的总大小为12 。
此时的内存状态为:
oxxx|oooo|ooxx
0123 4567 89ab (地址)
到此内存对齐结束。
St1占用了12个字节而非7个字节。
St2 的对齐方法和st1相同,读者可自己完成。
内存对齐的主要作用是:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:经过内存对齐后,CPU的内存访问速度大大提升。
具体原因稍后解释。
图一:
这是普通程序员心目中的内存印象,由一个个的字节组成,而CPU并不是这么看待的。
图二:
CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。
块大小成为memory accessgranularity(粒度)本人把它翻译为“内存读取粒度”。
假设CPU要读取一个int型4字节大小的数据到寄存器中,分两种情况讨论:
1、数据从0字节开始
2、数据从1字节开始
再次假设内存读取粒度为4。
图三:
当该数据是从0字节开始时,很CPU只需读取内存一次即可把这4字节的数据完全读取到寄存器中。
当该数据是从1字节开始时,问题变的有些复杂,此时该int型数据不是位于内存读取边界上,这就是一类内存未对齐的数据。
图四:
此时CPU先访问一次内存,读取0—3字节的数据进寄存器,并再次读取4—5字节的数据进寄存器,接着把0字节和6,7,8字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器。
对一个内存未对齐的数据进行了这么多额外的操作,大大降低了CPU性能。
这还属于乐观情况了,上文提到内存对齐的作用之一为平台的移植原因,因为以上操作只有有部分CPU肯干,其他一部分CPU遇到未对齐边界就直接罢工了。