__int128类型movaps指令crash

结论

在使用__int128时,如果__int128类型的内存起始地址不是按16字节对齐的话,有些汇编指令会抛出SIGSEGV使程序crash。

malloc在64位系统中申请的内存地址,是按16字节对齐的,但一般使用时经常会申请一块内存自己切割使用,往往会忽略一些类型的对齐。

案例

目前知道的两个指令是msse指令集的movaps和vmovaps,都是用来给int128赋值的,例如下面两种场景:

  1. (访问rax+0x30地址即 0x328dba8 + 0x30 = 0x328dbd8,对齐8字节,但没对齐16字节)
  2. (访问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肯定没问题)。

相关推荐
huangyuchi.4 天前
【Linux】编译器gcc/g++及其库的详细介绍
linux·运维·服务器·笔记·编译器·gcc·g++
爱出名的狗腿子6 天前
vscode + cmake + ninja+ gcc 搭建MCU开发环境
ide·vscode·单片机·c·cmake·gcc·ninja
Mr_Chenph10 天前
VSCode + GD32F407 构建&烧录
vscode·单片机·gcc·gd32f407
Tipriest_13 天前
ubuntu20.04&vscode使用C++20(调整gcc版本&vscode设置)
ide·vscode·c++20·gcc
belldeep14 天前
C语言:gcc 或 g++ 数组边界检查方法
c语言·gcc·数组边界检查
Strugglingler14 天前
编译器ar命令参数
linux·ar·gcc
百年孤独百年20 天前
Conda 环境下安装 GCC 和 glibc (crypt.h) 教程
conda·glibc·gcc·图像恢复·低光照增强
咖喱年糕20 天前
【Linux】系统指令与开发全栈(vim、ssh、gcc)
linux·ssh·vim·gcc
云空1 个月前
《Linux macOS :GCC升级方法》
linux·运维·macos·gcc
浅安的邂逅1 个月前
Linux进程7-signal信号处理方式验证、可重入函数举例、信号集函数验证、信号集阻塞验证
linux·c语言·vim·进程通信·gcc