我很好奇,看看我的64位应用程序是否存在对齐错误。
在Windows中,生成对齐错误的应用程序会引发异常,
EXCEPTION_DATATYPE_MISALIGNMENT
。
SEM_NOALIGNMENTFAULTEXCEPT
。(有关详细信息,请参阅AMD体系结构程序员手册第2卷:系统编程。)[编者按:强调我的]
忽略了参考AMD体系结构程序员手册的方向,我会参考英特尔64和IA-32体系结构软件开发人员手册
5.10.5检查对齐 当CPL为3时,可通过设置CR0寄存器中的AM标志和EFLAGS寄存器中的AC标志来检查内存引用的对齐情况。未对齐的内存引用会生成对齐异常(#AC)。在特权级别0,1或2下运行时,处理器不会生成对齐异常。有关启用对齐检查时对齐要求的说明,请参阅表6-7。
优秀。我不确定那是什么意思,但很好。
那么还有:
2.5控制寄存器 控制寄存器(CR0,CR1,CR2,CR3和CR4;参见图2-6)确定处理器的工作模式和当前正在执行的任务的特性。这些寄存器在所有32位模式和兼容模式下均为32位。 在64位模式下,控制寄存器扩展为64位。MOV CRn指令用于操作寄存器位。这些指令的操作数大小前缀将被忽略。 控制寄存器总结如下,并且这些控制寄存器中每个架构定义的控制字段都是单独描述的。在图2-6中,64位模式下寄存器的宽度用括号表示(CR0除外)。- CR0 - 包含控制处理器工作模式和状态的系统控制标志
AM 对齐掩码(CR0的第18位) - 设置时启用自动对齐检查; 在清除时禁用对齐检查。只有当AM标志置位,EFLAGS寄存器中的AC标志置位,CPL为3,处理器工作在保护模式或虚拟8086模式时,才进行对齐检查。
我实际使用的语言是Delphi,但假装它是语言不可知的伪代码:
void UnmaskAlignmentExceptions()
{
asm
mov rax, cr0; //copy CR0 flags into RAX
or rax, 0x20000; //set bit 18 (AM)
mov cr0, rax; //copy flags back
}
第一条指令
mov rax, cr0;
特权指令异常失败。
如何在x64上为我的进程启用对齐例外?
我发现x86有这样的说明:
PUSHF
,POPF
:在堆栈上打开/关闭首个16位EFLAGSPUSHFD
,POPFD
:按下/弹出所有32位EFLAGS的开/关堆栈然后,这导致我的x64版本:
PUSHFQ
,POPFQ
:在堆栈上打开/关闭RFLAGS quad(在64位的世界里,EFLAGS
它们被重新命名RFLAGS
)。
所以我写道:
void EnableAlignmentExceptions;
{
asm
PUSHFQ; //Push RFLAGS quadword onto the stack
POP RAX; //Pop them flags into RAX
OR RAX, $20000; //set bit 18 (AC=Alignment Check) of the flags
PUSH RAX; //Push the modified flags back onto the stack
POPFQ; //Pop the stack back into RFLAGS;
}
它没有崩溃或触发保护例外。我不知道它是否符合我的要求。
发布于 2018-03-29 09:24:50
在x64上运行的应用程序可以访问标志寄存器(有时称为EFLAGS)。此寄存器中的位18允许应用程序在发生对齐错误时获得异常。所以从理论上讲,所有的程序都必须这样做才能使对齐错误的异常是修改标志寄存器。
为了实际工作,操作系统内核必须设置cr0的位18来允许它。而Windows操作系统并没有这样做。为什么不?谁知道?
应用程序不能在控制寄存器中设置值。只有内核可以做到这一点。设备驱动程序在内核中运行,所以他们也可以设置它。
可以通过创建一个设备驱动程序来解决这个问题,并尝试通过它来工作(请参阅http://blogs.msdn.com/b/oldnewthing/archive/2004/07/27/198410.aspx#199239以及注释以下)。请注意,这篇文章已经超过十年了,所以一些链接已经死了。
发布于 2018-03-29 10:03:18
这适用于64位Intel CPU。某些AMD可能会失败
pushfq
bts qword ptr [rsp], 12h ; reset AC bit of rflags
popfq
它在32位CPU中不会立即工作,它们将首先需要内核驱动程序来更改CR0的AM位,然后
pushfd
bts dword ptr [esp], 12h
popfd
https://stackoverflow.com/questions/-100007852
复制相似问题