代码是最小的:
用两个条目(NULL和代码描述符)设置GDT。
尝试将远jmp插入新安装的代码部分。
但在最后一步,我得到了#GP(0)。为什么?
下面是代码(在64位模式下从已经运行的运行):
call do_lgdt # 'do_lgdt' is defined at the bottom
push $(1<<3) # Push code-selector,TI=0,RPL=0
lea func(%rip),%rax # The (relocated) address of '
已经有一个问题被问到了:undefined reference to `__stack_chk_fail',但这个问题是对__stack_chk_fail而不是__stack_chk_fail_local的未定义引用。这是我得到的一个链接器错误,我已经搜索过了,但我不知道如何修复它。这就是确切的错误: ld: binaries/GlobalDescriptorTable.o: in function
`GlobalDescriptorTable::GlobalDescriptorTable()':
GlobalDescriptorTable.cpp:(.text+0xa6)
这是一段将cpu切换到32位模式的标准代码。
cli
lgdt [gdt_descriptor] ; Assume a well-defined GDT
mov eax, cr0
or eax, 0x1
mov cr0, eax; Is this the exact moment when the processor switches to 32 bit mode?
jmp CODE_SEG:pipeline_flush ; Here CODE_SEG is 0x08,i.e, the segment descriptor after
我正在为内核编写一个GDT,一切都很顺利,我将遵循本教程。
当将C代码链接到汇编代码时,他使用这段代码。
; This will set up our new segment registers. We need to do
; something special in order to set CS. We do what is called a
; far jump. A jump that includes a segment as well as an offset.
; This is declared in C as 'extern void gdt_flush();
我正在开发一个操作系统,我想从监视器获取EDID,我发现一些asm代码()可以在ES:DI寄存器中获得edid,
mov ax, 0x4f15
mov bl, 0x01
xor cx, cx
xor dx, dx
int 0x10
;AL = 0x4F if function supported
;AH = status (0 is success, 1 is fail)
;ES:DI contains the EDID
如何在C文件中获得AL、AH和ES:DI值?
实际上我正在开发一个64位UEFI操作系统
LoadGDT:
lg
最近我正在查看Linux0.01源代码,因为2.6.11中的bootsect.S和更高版本是无用的,它是开始学习linux代码的好地方,因此我选择跟踪linux的第一个版本。:P
我在bootsect.S中有一些问题。下面是bootsect.S linux v0.01中的一些代码。
第一个版本的汇编代码使用的是英特尔语法,而不是at&t。
mov ax,#0x0001 | protected mode (PE) bit
lmsw ax | This is it!
jmpi 0,8 | jmp offset 0 of segment 8 (cs) which
我试图在铁锈和全球asm中设置GDT,但当我尝试加载GDT时,它似乎是三重故障。
# init_gdt.asm.
.intel_syntax noprefix
# **Notes**: 0x00: The Kernel Null Segment.
# 0x10: The Kernel Data Segment.
# 0x08: The Kernel Code Segment.
# Load the GDT and set all of the segments.
LoadGDT:
# Use the `lgdt` Load GDT ins
我是根据尼克·布兰德尔的一本书这么做的。我编写了一个MBR程序,它首先以实模式运行,程序中的一些指令将cpu切换到保护模式。首先,我把GDT设成这样:
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_code:
dw 0xffff
dw 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data:
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_en
我目前正在编写一些小内核代码。下面是我从某个内核项目中复制的内容。它包含将内核加载到内存位置0x1000并跳转到0x1000位置的代码:
;
; The Bootsector Code (First 512 bytes of the floppy)
;
;
; Define Code Segment and Data Segment Rights details for inputting to GDTFill function
;
%define CS_ACCES 10011011b ; CS and DS Access Rights (Details in GDT.INC)
%defin