Search code examples
assemblyoperating-systemx86-64memory-segmentation

Zero stack segment in amd64 in long mode


This code stub was extracted from linux kernel 3.18.3, arch/x86/boot/compressed/head_64.S. There were added extra comments though.

All this code is executed in long mode (64 bits) with code segment selector: 0x10 and data segment selector: 0x18

xorl    %eax, %eax /* Setting up all data segments selectors to zero */
movl    %eax, %ds  /* Including stack segment */
movl    %eax, %es
movl    %eax, %ss
movl    %eax, %fs
movl    %eax, %gs

leaq    z_extract_offset(%rbp), %rbx

/* Set up the stack */
leaq    boot_stack_end(%rbx), %rsp

/* Zero EFLAGS */
pushq   $0 /* This instruction should fail since stack segment selector */
popfq      /* is zero (pointing to null descriptor) /*

According to what I know this code should fail to execute because %ss = 0x0 which points to null descriptor in the gdt, when the stack instruction pushq is executed.

Nevertheless this seems to work, so I assume I'm missing some information. Why does this work?


Solution

  • Segmentation is mostly disabled in 64-bit mode, with only attributes of CS and the base of FS and GS being used.