Enable alignement exception on x64 (under Windows x64)

Enable alignement exception on x64 (under Windows x64)

Post by Gilles Vol » Sat, 09 Apr 2005 03:25:15


To help me discover alignement problem in an application I developp (because
there is a little performance impact on x64 and, if I compile after on
Itanium, a very high performance impact OR crash on Itanium), I want enable
the exception for alignement problem.

on page
I found
" On the x86-64 architecture, the alignment exceptions are disabled by
default, and the fix-ups are done by the hardware. The application can
enable alignment exceptions by setting a couple of register bits, in which
case the exceptions will be raised unless the user has the operating system
mask the exceptions with SEM_NOALIGNMENTFAULTEXCEPT. (For details, see the
AMD x86-64 Architecture Programmer's Manual Volume 2: System Programming.) "

I read after

http://www.yqcomputer.com/ ,,30_182_739_7044,00.html
(page 303 of PDF, page 263 on the document numbering)

"An #AC exception occurs when an unaligned-memory data reference is
performed while alignment checking is enabled.
After a processor reset, #AC exceptions are disabled. Software enables the
#AC exception by setting the following register bits:

- CR0.AM=1.


When the above register bits are set, an #AC can occur only when CPL=3. #AC
never occurs when CPL < 3. "

I just need an help to a enable the exception. Pehaps this is just translate
the two bits register to set to a .asm function (sorry, I did not known how
perform this).

Any comment welcome ! :-)

Enable alignement exception on x64 (under Windows x64)

Post by Alex » Sat, 09 Apr 2005 10:36:21

On Thu, 7 Apr 2005 18:25:15 +0000 (UTC), Gilles Vollant


Setting CR0 will require Ring-0 privileges. You're not going to get
that without writing some kind of kernel-mode driver.
However, once you've got it, this should do the trick:

mov eax, cr0
or eax, <the bit in the AM position>
mov cr0, eax

Not sure about the flags, but anything that modifies the system flags
will also require Ring-0 access.

Alex Davidson


'You are in the presence of a System Administrator. KNEEL.' --Unknown


Enable alignement exception on x64 (under Windows x64)

Post by Gilles Vol » Sun, 10 Apr 2005 04:35:40

I found the solution
cr0 is already set as needed under Windows x64.

; begin of setacx64.asm

; see
; for calling convention
; to compile this file, run "ml64 /c /Zi setacx64.asm"
setac PROC
pop rax
or rax, 40000h
push rax
setac ENDP
; end of setacx64.asm

Include setacx64.obj in the linker additional dependency, and in C or
C++ source

extern "C" unsigned __int64 setacx64(void);

after executing "setacx64()" in C++ souce, I get "exception 0x80000002
: Datatype misalignment" on my x64 computer when I acces to unaligned data.
I have the same debug report than Itanium !

Finally, what I suggest :
- on your debug build, and on all your testing build, add a call to
"setacx64" at the beginning your your application, to discover alignement
problem, on AMD64/EM64T build.
- on your final build (shipped to real user), remove the setacx64 on
x64 build and add SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT);

So, if an alignement problem comes a day on Itanium, you'll not crash
(the application will only be slower, this is far better than crash )!

At least, there is only one problem :

On Itanium, when you add UNALIGNED or _unaligned keyword on a pointer,
the compiler add specific code to check pointer alignement, so it'll never
generate exception, and this will be only a bit slower (slower than aligned
data, a lot faster than exception).

On x64, UNALIGNED or _unaligned keyword does ... nothing, because
standard x64 behavoiur is don't generate exception. So if you use my
function to enable alignement exception, you'll have exception on access
with UNALIGNED keyword.

But my method is good if you decide not using UNALIGNED keyword
because your application is designed to don't access unaligned data, and
unaligned acces is an error.