| 发表于:2007-03-16 21:20:27 楼主 |
; pmtest1.asm ; 编译方式:nasm pmtest1.asm -o pmtest1.com %include "pm.inc " ; 常量、宏,以及一些说明 org 0100h jmp label_begin [section .gdt] ; gdt label_gdt: descriptor 0, 0, 0 ; 空描述符 label_desc_code32: descriptor 0, segcode32len-1, da_c + da_32 ; 代码段,32位 label_desc_video: descriptor 0b800h, 0ffffh, da_drw ; 显存首地址 ; gdt 结束 gdtlen equ $ - label_gdt ; gdt长度 gdtptr dw gdtlen -1 ; gdt界限 dd 0 ; gdt 选择子 selectorcode32 equ label_desc_code32 - label_gdt selectorvideo equ label_desc_video - label_gdt ; end of [section .gdt] [section .s16] [bits 16] label_begin: mov ax, cs mov ds, ax mov es, ax mov ss, ax mov sp, 0100h ; 初始化32位代码段描述符 xor eax, eax mov ax, cs shl eax, 4 add eax, label_seg_code32 mov word [label_desc_code32+2], ax shr eax, 16 mov byte [label_desc_code32+4], al mov byte [label_desc_code32+7], ah ; 为加载gdtr做准备 xor eax, eax mov ax, ds shl eax, 4 add eax, label_gdt ; eax <- gdt 基地址 mov dword [gdtptr+2], eax ; [gdtptr+2] <- gdt 基地址 ; 加载gdtr lgdt [gdtptr] ; 关中断 cli ; 打开地址线a20 in al, 92h or al, 00000010b out 92h, al ; 准备进入保护模式 mov eax, cr0 or eax, 1 mov cr0, eax ; 真正计入保护方式 jmp dword selectorcode32:0 ; 执行这一句会把selectorcode32 ; 装入cs,并跳转到selectorcode32:0 处 [section .s32] ; 32位代码段,由实模式跳入 [bits 32] label_seg_code32: mov ax, selectorvideo mov gs, ax ; 视频段选择子(目的) mov edi, (80 * 10 + 0) * 2 ; 屏幕第10行,第0行 mov ah, 0ch ; 0000:黑底 1100:红字 mov al, 'p ' mov [gs:edi], ax ; 到此停止 jmp $ segcode32len equ $-label_seg_code32 ; end of [section .s32] 摘自仓库: mov ax, cs mov ds, ax mov es, ax mov ss, ax mov sp, 0100h 不明白其意,为何要把其他寄存器的值都指向cs? 请详解,另外不明白的是为什么要 mov sp, 0100h 在该示例中没有call之类的指令,没有用到堆栈,为什么要多出这个指令, 机子加电以后堆栈如何分布?这个0100h从何而来?? 谢谢 |
|
|
|
|