堆栈,GDT切换纯汇编版

     前两天把第五章基本看完了,刚开始看的时候头脑很乱,作者把整个工程分成了好几个目录,又拆了好几个头文件。这样做无疑是非常正确的,如果把所有的代码都堆在一起,不但改起来难找,而且改一个模块的话就要整个工程重新编译链接。但对于初学者来说一开始还难以适应这种方式,尤其是汇编跟C的代码互相调来调去,容易看花眼。而且分成多个文件的话,必须写MAKEFILE来编译,要不然会吐血的。

    适应总是要有一个过程的,我就想一开始用汇编写完整个第五章的要求,然后看看有哪些模块是必须用汇编写的,哪些模块是可以用C写的,汇编毕竟晦涩难懂,远远没有C来得畅快。下面就祭上堆栈,GDT切换纯汇编版:

;编译链接方法

;nasm -f elf -o kernel.o kernel.asm

;ld -s -Ttext 0x30400 -o kernel.bin kernel.o

%include "pm.inc"

[section .data]

LABEL_DESC_GDT:     Descriptor 0,0,0
LABEL_DESC_FLAT_RW:   Descriptor  0,0ffffh,DA_DRW + DA_32 + DA_LIMIT_4K
LABEL_DESC_FLAT_C:   Descriptor  0,0ffffh,DA_CR + DA_32 + DA_LIMIT_4K
LABEL_DESC_VIDEO:    Descriptor  0b8000h,0ffffh,DA_DRW

Selector_Flat_RW  equ  LABEL_DESC_FLAT_RW - LABEL_DESC_GDT
Selector_Flat_C   equ  LABEL_DESC_FLAT_C  - LABEL_DESC_GDT
Selector_Video   equ  LABEL_DESC_VIDEO - LABEL_DESC_GDT

Selector_Loader_Flat_RW  equ  8
Selector_Loader_Flat_C  equ  16

 

GDT_Len  equ $ - LABEL_DESC_GDT
GDT_Ptr: dw GDT_Len - 1
     dd  0
    
A: db 'A'
    
[section .bss]


Stack_Space  resb 2 * 1024
Top_Of_Stack:

 


[section .text]

global _start
 
_start:
 mov ax,Selector_Loader_Flat_RW
 mov ds,ax
 mov es,ax
 
 mov eax,LABEL_DESC_GDT
 mov dword [GDT_Ptr],eax
 
 lgdt [GDT_Ptr]
 
 mov ax,Selector_Flat_RW
 mov ds,ax
 mov es,ax
 mov ss,ax
 mov esp,Top_Of_Stack
 
 jmp Selector_Flat_C:LABEL_TEST
 
LABEL_TEST:
 mov ax,Selector_Video
 mov gs,ax
 mov ah,0ch
 mov byte al,[A]
 mov [gs:(80 * 20) * 2],ax
 
 hlt

 

    这里没有像作者那样把GDT从loader拷到kernel中,而是直接分配填充GDT,代码很简单,无需赘言,最后附图一张:

你可能感兴趣的:(c,汇编,video,include,makefile,Descriptor)