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

标签 c visual-studio

有一个大小为 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/

相关文章:

objective-c - Objective-c 中的位交织

c - 如何替换文件中特定人物的字符串

c++ - 在 Windows 7 上静态构建 Qt 5.1.1 - nmake 和 cl 错误

c - 如何在frama-c wp中用计算证明迭代循环?

c - 如何使用共享库中的方法

c - C 中的格式说明符行为

node.js - 为什么 sequelize Intellisense 不起作用?

visual-studio - 设备的 Ad-Hoc 代码设计在 Studio 中成功,在 Jenkins 中失败

c++ - 在调试中将 QUrl 可视化为 VS 中的字符串

c# - xsd.exe 将类生成为单独的文件?