Archive for December, 2009
Unaligned access
By chys on December 26th, 2009Misalignment is not an error (only incurs a performance penalty) on x86 processors except for a few new instructions added in recent years. MOVDQA, for example, is an SSE2 instruction requiring alignment on 16-byte boundaries.
Textbooks have normally taught us we get a bus error if a CPU which disallows unaligned access actually encounters one.
But we observe a Linux process passing misaligned addresses to MOVDQA receives SIGSEGV (segmentation fault) instead of SIGBUS (bus error), on both ia32 and x86-64.
laptop /tmp $ cat a.c
int main ()
{
char X[32];
asm ("pxor %%xmm0,%%xmm0; movdqa %%xmm0,%0" : "=m"(X[1]) :: "xmm0");
return 0;
}
laptop /tmp $ gcc -msse2 a.c
laptop /tmp $ ./a.out
Segmentation fault
laptop /tmp $ kill -l $?
SEGV
x86-64 (and ia32 beginning 80486SX) supports disallowing any misaligned access*. In that case, a normal instruction raises SIGBUS, but instructions which inherently requires alignment (e.g. MOVDQA) still raises SIGSEGV. It’s not so consistent.
* It is normally disabled. To enable it, set the AC bit in FLAGS:
pushf
or $0x40000,(%esp)(or%rspon x86-64)
popf
Floating point exception
By chys on December 1st, 2009It is already confusing enough that “floating point exception” may mean “division by zero” in integral arithmetic. It turns out it can also mean “overflow” in some cases, as in the following program (it’s difficult in C, so I had to use assembly):
#include <asm/unistd.h>
.code:
.globl _start
_start:
mov $1, %eax
mov $1, %edx
div %eax
mov $__NR_exit_group, %eax
int $0x80
(Type “gcc -m32 -nostdlib a.S” to compile and link.)
In this program, EDX:EAX (0x100000001) divided by ECX (0x1) cannot be represented in 32-bit integer and thus it is an overflow. X86 CPUs raise a “division by zero” interruption (int 0) in such cases, and “division by zero” is displayed as “floating point exception” in Linux…
PS. The same assembly program in Intel style:
.code
.startup
MOV EAX,1
MOV EDX, 1
DIV EAX
MOV EAX, __NR_exit_group
INT 80H
