【发布时间】:2015-10-16 21:21:03
【问题描述】:
此代码存根提取自 linux 内核 3.18.3,arch/x86/boot/compressed/head_64.S。不过也增加了额外的 cmets。
所有这些代码都以长模式(64 位)执行,代码段选择器:0x10 和数据段选择器: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) /*
据我所知,这段代码应该无法执行,因为 %ss = 0x0 在执行堆栈指令 pushq 时指向 gdt 中的空描述符。
尽管如此,这似乎可行,所以我认为我遗漏了一些信息。 为什么会这样?
【问题讨论】:
-
长模式 == IA-32e 模式 Intel 说话吗?英特尔手册似乎说,只需将 SS 设置为 0 就会出现异常:stackoverflow.com/a/33198311/895245
标签: assembly operating-system x86-64 memory-segmentation