結論
在使用__int128時,如果__int128類型的內存起始地址不是按16字節對齊的話,有些匯編指令會拋出SIGSEGV使程序crash。
malloc在64位系統中申請的內存地址,是按16字節對齊的,但一般使用時經常會申請一塊內存自己切割使用,往往會忽略一些類型的對齊。
案例
目前知道的兩個指令是msse指令集的movaps和vmovaps,都是用來給int128賦值的,例如下面兩種場景:
- (訪問rax+0x30地址即 0x328dba8 + 0x30 = 0x328dbd8,對齊8字節,但沒對齊16字節)
- (訪問rax+0x30地址即 0x2d20b48 + 0x20 = 0x2d20b68,對齊8字節,但沒對齊16字節)
復現
#include <stdio.h>// gcc -g -O2 -Wall -msse4.2 -o test test.c// core
typedef unsigned __int128 uint128;// no core
// typedef unsigned __int128 uint128 __attribute__((aligned(8)));static char mem[100];typedef struct MySt
{int a;uint128 i;int b;
} MySt;int main(void)
{MySt *st = (MySt *)(mem + 1);printf("st = %p\n", st);printf("st->i = %p\n", &st->i);__int128 tmp = 123123;st->a = 0;st->i = tmp * 123;st->b = 0;st = st;return st->i + 1 == 123;
}
gcc -g -O2 -Wall -msse4.2 -o test test.c
可復現(不同的機器、編譯器版本有不同的效果,可以看下編出來的二進制有無movaps指令,如果都是mov肯定沒問題)。