So I’m trying to load my GDT on a x86_64 long mode emulator This is the inline assembly which I’ve written to reload the code and data segments
asm volatile (
\\xor %%rax, %%rax
\\movw %[ds], %%ax
\\mov %%ax, %%ds
\\movw %%ax, %%ss
\\movw %%ax, %%es
\\movw %%ax, %%fs
\\movw %%ax, %%gs
\\push %[cs]
\\push %[dummy]
\\lretq
:
: [ds] "i" (DATA_SEG),
[cs] "i" (CODE_SEG),
[dummy] "r" (&dummy_ret),
: "stack", "rax"
);
Now the code and the data segments on x86_64 are 16bits which means the generated assembly should use some form of “ax” registers but dumping the disassembly, I can see that the generated disassembly is using eax
400001ce3e: 48 31 c0 xor %rax,%rax
400001ce41: 66 b8 10 00 mov $0x10,%ax
400001ce45: 8e d8 mov %eax,%ds
400001ce47: 8e d0 mov %eax,%ss
400001ce49: 8e c0 mov %eax,%es
400001ce4b: 8e e0 mov %eax,%fs
400001ce4d: 8e e8 mov %eax,%gs
400001ce4f: 6a 08 push $0x8
400001ce51: 51 push %rcx
400001ce52: 48 cb lretq
and sure enough the qemu triple faults on the same instruction
Triple fault
CPU Reset (CPU 0)
RAX=0000000000000010 RBX=0000000000000000 RCX=000000400001d640 RDX=0000004000055190
RSI=00af00000000ffff RDI=00000040000578a0 RBP=0000004000057760 RSP=0000004000057750
R8 =000000000000000a R9 =000000000000000a R10=0000000000000000 R11=000000400005767f
R12=0000000000000000 R13=000000001e280000 R14=000000001e9ee098 R15=000000001e14b018
RIP=000000400001ce45 RFL=00000046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
Am I missing something?