[英]General Protection Exception due to unaligned memory access with SSE instructions
有一个大小为 68 字节的 C 结构,它作为参数传递给另一个 function 说 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;
}
在反汇编代码中(不是上面的代码,只说明了场景),我们看到在 function 调用(Temp)之前使用了 SSE(MOVAPS)指令。 这些指令的 memory 操作数似乎未对齐,这会触发一般保护异常。 使用的优化级别是/O1b2s。 请注意,禁用优化后不会出现此问题。 源代码最初是使用 Visual Studio 2008 编译的,但未观察到此问题。 编译器升级到 Visual Studio 2017 并发布开始浮出水面。
我们现在的解决方法是 1. 使用 /Ob2 作为编译器优化级别 2. 使用 #pragma optimize(off) 和 #pragma optimize(on)
这两种解决方法都有影响。 对于第一个解决方法,代码大小显着增加,但存在大小限制。 我们仍在评估第二种解决方法的后果。
代码的scope是在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 字节大小相匹配。
如果这是已在 VS2019 中修复的 VS2017 中的错误,那么我建议您转移到新的编译器。 特别是它与 VS2017 兼容的 ABI。 试试看?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.