gpt4 book ai didi

c - 由于 SSE 指令未对齐内存访问而导致的一般保护异常

转载 作者:行者123 更新时间:2023-11-30 16:10:30 25 4
gpt4 key购买 nike

有一个大小为 68 字节的 C 结构体,它作为参数传递给另一个函数是 Temp。

#pragma pack(1)
struct A {
char [68];
};
#pragma pack()


void Temp(struct A)
{
/*
some code goes here
*/
}

int main()
{
struct A var1;

Temp(var1); //-> SSE instructions are generated for this call (MOVAPS ...)

return 0;
}

在反汇编代码中(不是上面的代码,只是说明场景),我们看到SSE(MOVAPS)在函数调用(Temp)之前使用指令。这些指令的内存操作数似乎未对齐会触发一般保护异常。使用的优化级别是/O1b2s。请注意,禁用优化后不会出现此问题。源代码最初是使用 Visual Studio 2008 进行编译的,但未观察到此问题。编译器升级到 Visual Studio 2017,并且问题开始出现。

我们现在的解决方法是1.使用/Ob2作为编译器优化级别2.使用#pragma optimize(off)和#pragma optimize(on)

这两种解决方法都有影响。对于第一个解决方法,代码大小显着增加上涨,但有规模限制。我们仍在评估第二种解决方法的后果。

代码的范围在 UEFI 环境中。

任何避免这种情况的建议将不胜感激。

最佳答案

这听起来像是一个编译器错误。但是我无法使用 Visual Studio 2019 (16.3.9) 重现此问题

这是我使用的代码:

#include <stdio.h>

#pragma pack(1)
struct A {
char field[68];
};
#pragma pack()


__declspec(noinline) void Temp(struct A a)
{
if (a.field[3] != 0)
{
printf("hello world\n");
}
}

int main()
{
struct A var1 = {0};

Temp(var1); //-> SSE instructions are generated for this call (MOVAPS ...)

return 0;
}

生成的程序集是

Temp(var1); //-> SSE instructions are generated for this call (MOVAPS ...)
00007FF710D510A4 movaps xmmword ptr [rbp+7],xmm0
00007FF710D510A8 movaps xmm0,xmmword ptr [rbp-29h]
00007FF710D510AC movaps xmmword ptr [rbp+17h],xmm1
00007FF710D510B0 movaps xmm1,xmmword ptr [rbp-19h]
00007FF710D510B4 movaps xmmword ptr [rbp+27h],xmm0
00007FF710D510B8 movaps xmmword ptr [rbp+37h],xmm1
00007FF710D510BC mov dword ptr [rbp+47h],eax
00007FF710D510BF call Temp (07FF710D5105Ch)

我数了一下,有 4 个 MOVAPS 和 1 个 MOV DWORD。这似乎与您指定的 68 字节大小相匹配。

如果这是 VS2017 中的错误并已在 VS2019 中修复,那么我建议您迁移到新的编译器。特别是它与 VS2017 兼容 ABI。尝试一下吗?

关于c - 由于 SSE 指令未对齐内存访问而导致的一般保护异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58874445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com