【日拱一卒行而不辍20220925】自制操作系统
下面这段系统联调的代码始终没有调通。需要进一步排查。
在汇编层面,下述代码已经进入了综合的深水区。
; ==========================================
; pmtest1.asm
; 编译方法:nasm pmtest.asm -o pmtest.bin
; ==========================================
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
org 07c00hjmp LABEL_BEGIN
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
[SECTION .s16A]
[BITS 16]
LABEL_BEGIN:xor ax,ax ; 为 DS 置 0 准备mov ds,axmov ah, 0x02;al=1 load sec2;al=2 load sec2-3;al=3 load sec2-4mov al, 5mov ch, 0mov cl, 2mov dh, 0mov bx, sect2mov es, bxxor bx, bxint 0x13jmp sect2:0
data:sect2 equ 0x0588
times 506-($-$$) db 0
dw 0xaa55
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
;sect2:mov ax, csmov ds, ax ; 设置 CS=DS. CS=0x0500, 因此 DS=0x500; 如果变量已经在代码中设置,则要求; 正确地引用其内存地址
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------mov ax, 0xB800mov es, axmov byte [es:(80 * 20 + 0) * 2], '1'mov byte [es:(80 * 20 + 1) * 2], '2'mov byte [es:(80 * 20 + 2) * 2], '3'mov byte [es:(80 * 20 + 3) * 2], '4'mov byte [es:(80 * 20 + 4) * 2], '5'
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
%include "pm.inc" ;PageDirBase0 equ 200000h ; 页目录开始地址: 2M
PageTblBase0 equ 201000h ; 页表开始地址: 2M + 4K
PageDirBase1 equ 210000h ; 页目录开始地址: 2M + 64K
PageTblBase1 equ 211000h ; 页表开始地址: 2M + 64K + 4KLinearAddrDemo equ 00401000h
ProcFoo equ 00401000h
ProcBar equ 00501000h
ProcPagingDemo equ 00301000h
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------mov ax, 0xB800mov es, axmov byte [es:(80 * 21 + 0) * 2], 'a'mov byte [es:(80 * 21 + 1) * 2], 'b'mov byte [es:(80 * 21 + 2) * 2], 'c'mov byte [es:(80 * 21 + 3) * 2], 'd'mov byte [es:(80 * 21 + 4) * 2], 'e'
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW ; Normal 描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32; 非一致代码段,32
LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C ; 非一致代码段,16
LABEL_DESC_CODE_DEST: Descriptor 0,SegCodeDestLen-1, DA_C+DA_32; 非一致代码段,32
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW ; Data
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA+DA_32;Stack, 32 位
LABEL_DESC_LDT: Descriptor 0, LDTLen-1, DA_LDT ; LDT
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址; 门 目标选择子,偏移,DCount, 属性
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate+DA_DPL0
;--------------------------------------------------------------------------------------mov ax, 0xB800mov es, axmov byte [es:(80 * 22 + 0) * 2], 'e'mov byte [es:(80 * 22 + 1) * 2], 'n'mov byte [es:(80 * 22 + 2) * 2], 'd'
;--------------------------------------------------------------------------------------
; GDT 结束GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限dd 0 ; GDT基地址; GDT 选择子
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorCodeDest equ LABEL_DESC_CODE_DEST - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorLDT equ LABEL_DESC_LDT - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDTSelectorCallGateTest equ LABEL_CALL_GATE_TEST - LABEL_GDT
; END of [SECTION .gdt];--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
[SECTION .s16B]
[BITS 16];--------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------- mov ax, csmov ds, axmov es, axmov ss, axmov sp, 0100hmov [LABEL_GO_BACK_TO_REAL+3], axmov [SPValueInRealMode], sp; 初始化 16 位代码段描述符mov ax, csmovzx eax, axshl eax, 4add eax, LABEL_SEG_CODE16mov word [LABEL_DESC_CODE16 + 2], axshr eax, 16mov byte [LABEL_DESC_CODE16 + 4], almov byte [LABEL_DESC_CODE16 + 7], ah; 初始化 32 位代码段描述符xor eax, eaxmov ax, csshl eax, 4add eax, LABEL_SEG_CODE32mov word [LABEL_DESC_CODE32 + 2], axshr eax, 16mov byte [LABEL_DESC_CODE32 + 4], almov byte [LABEL_DESC_CODE32 + 7], ah; 初始化测试调用门的代码段描述符xor eax, eaxmov ax, csshl eax, 4add eax, LABEL_SEG_CODE_DESTmov word [LABEL_DESC_CODE_DEST + 2], axshr eax, 16mov byte [LABEL_DESC_CODE_DEST + 4], almov byte [LABEL_DESC_CODE_DEST + 7], ah; 初始化数据段描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_DATAmov word [LABEL_DESC_DATA + 2], axshr eax, 16mov byte [LABEL_DESC_DATA + 4], almov byte [LABEL_DESC_DATA + 7], ah; 初始化堆栈段描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_STACKmov word [LABEL_DESC_STACK + 2], axshr eax, 16mov byte [LABEL_DESC_STACK + 4], almov byte [LABEL_DESC_STACK + 7], ah; 初始化 LDT 在 GDT 中的描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_LDTmov word [LABEL_DESC_LDT + 2], axshr eax, 16mov byte [LABEL_DESC_LDT + 4], almov byte [LABEL_DESC_LDT + 7], ah; 初始化 LDT 中的描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_CODE_Amov word [LABEL_LDT_DESC_CODEA + 2], axshr eax, 16mov byte [LABEL_LDT_DESC_CODEA + 4], almov byte [LABEL_LDT_DESC_CODEA + 7], ah; 为加载 GDTR 作准备xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_GDT ; eax <- gdt 基地址mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址; 加载 GDTRlgdt [GdtPtr]; 关中断cli; 打开地址线A20in al, 92hor al, 00000010bout 92h, al; 准备切换到保护模式mov eax, cr0or eax, 1mov cr0, eax; 真正进入保护模式jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 处LABEL_REAL_ENTRY: ; 从保护模式跳回到实模式就到了这里mov ax, csmov ds, axmov es, axmov ss, axmov sp, [SPValueInRealMode]in al, 92h ; ┓and al, 11111101b ; ┣ 关闭 A20 地址线out 92h, al ; ┛sti ; 开中断mov ax, 4c00h ; ┓int 21h ; ┛回到 DOS
; END of [SECTION .s16]
; END of [SECTION .s16];--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
[SECTION .data1] ; 数据段
ALIGN 32
[BITS 32]
LABEL_DATA:
SPValueInRealMode dw 0
; 字符串
PMMessage: db "In Protect Mode now. ^-^", 0 ; 进入保护模式后显示此字符串
OffsetPMMessage equ PMMessage - $$
StrTest: db "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
OffsetStrTest equ StrTest - $$
DataLen equ $ - LABEL_DATA
; END of [SECTION .data1]
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
; 全局堆栈段
[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:times 512 db 0TopOfStack equ $ - LABEL_STACK - 1; END of [SECTION .gs]
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]LABEL_SEG_CODE32:mov ax, SelectorDatamov ds, ax ; 数据段选择子mov ax, SelectorVideomov gs, ax ; 视频段选择子mov ax, SelectorStackmov ss, ax ; 堆栈段选择子mov esp, TopOfStack; 下面显示一个字符串mov ah, 0Ch ; 0000: 黑底 1100: 红字xor esi, esixor edi, edimov esi, OffsetPMMessage ; 源数据偏移mov edi, (80 * 10 + 0) * 2 ; 目的数据偏移。屏幕第 10 行, 第 0 列。cld
.1:lodsbtest al, aljz .2mov [gs:edi], axadd edi, 2jmp .1
.2: ; 显示完毕call DispReturn; 测试调用门(无特权级变换),将打印字母 'C'call SelectorCallGateTest:0;call SelectorCodeDest:0; Load LDTmov ax, SelectorLDTlldt axjmp SelectorLDTCodeA:0 ; 跳入局部任务,将打印字母 'L'。; ------------------------------------------------------------------------
DispReturn:push eaxpush ebxmov eax, edimov bl, 160div bland eax, 0FFhinc eaxmov bl, 160mul blmov edi, eaxpop ebxpop eaxret
; DispReturn 结束
SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
[SECTION .sdest]; 调用门目标段
[BITS 32]LABEL_SEG_CODE_DEST:;jmp $mov ax, SelectorVideomov gs, ax ; 视频段选择子(目的)mov edi, (80 * 12 + 0) * 2 ; 屏幕第 12 行, 第 0 列。mov ah, 0Ch ; 0000: 黑底 1100: 红字mov al, 'C'mov [gs:edi], axretfSegCodeDestLen equ $ - LABEL_SEG_CODE_DEST
; END of [SECTION .sdest]
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式
[SECTION .s16code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:; 跳回实模式:mov ax, SelectorNormalmov ds, axmov es, axmov fs, axmov gs, axmov ss, axmov eax, cr0and al, 11111110bmov cr0, eaxLABEL_GO_BACK_TO_REAL:jmp 0:LABEL_REAL_ENTRY ; 段地址会在程序开始处被设置成正确的值Code16Len equ $ - LABEL_SEG_CODE16; END of [SECTION .s16code]
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
; LDT
[SECTION .ldt]
ALIGN 32
LABEL_LDT:
; 段基址 段界限 , 属性
LABEL_LDT_DESC_CODEA: Descriptor 0, CodeALen - 1, DA_C + DA_32 ; Code, 32 位LDTLen equ $ - LABEL_LDT; LDT 选择子
SelectorLDTCodeA equ LABEL_LDT_DESC_CODEA - LABEL_LDT + SA_TIL
; END of [SECTION .ldt]
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
; CodeA (LDT, 32 位代码段)
[SECTION .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:mov ax, SelectorVideomov gs, ax ; 视频段选择子(目的)mov edi, (80 * 13 + 0) * 2 ; 屏幕第 13 行, 第 0 列。mov ah, 0Ch ; 0000: 黑底 1100: 红字mov al, 'L'mov [gs:edi], axhlt; 准备经由16位代码段跳回实模式jmp SelectorCode16:0
CodeALen equ $ - LABEL_CODE_A
; END of [SECTION .la]
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
内存分布如下:
as@as-virtual-machine:~/osdir/chapter3G$ hexdump -Cv boot
00000000 e9 01 00 00 31 c0 8e d8 b4 02 b0 05 b5 00 b1 02 |....1...........|
00000010 b6 00 bb 88 05 8e c3 31 db cd 13 ea 00 00 88 05 |.......1........|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200 8c c8 8e d8 b8 00 b8 8e c0 26 c6 06 80 0c 31 26 |.........&....1&|
00000210 c6 06 82 0c 32 26 c6 06 84 0c 33 26 c6 06 86 0c |....2&....3&....|
00000220 34 26 c6 06 88 0c 35 b8 00 b8 8e c0 26 c6 06 20 |4&....5.....&.. |
00000230 0d 61 26 c6 06 22 0d 62 26 c6 06 24 0d 63 26 c6 |.a&..".b&..$.c&.|
00000240 06 26 0d 64 26 c6 06 28 0d 65 00 00 00 00 00 00 |.&.d&..(.e......|
00000250 00 00 00 00 ff ff 00 00 00 92 00 00 66 00 00 00 |............f...|
00000260 00 98 40 00 ff ff 00 00 00 98 00 00 13 00 00 00 |..@.............|
00000270 00 98 40 00 35 00 00 00 00 92 00 00 ff 01 00 00 |..@.5...........|
00000280 00 93 40 00 07 00 00 00 00 82 00 00 ff ff 00 80 |..@.............|
00000290 0b 92 00 00 00 00 20 00 00 8c 00 00 b8 00 b8 8e |...... .........|
000002a0 c0 26 c6 06 c0 0d 65 26 c6 06 c2 0d 6e 26 c6 06 |.&....e&....n&..|
000002b0 c4 0d 64 66 00 00 00 00 00 00 00 00 8c c8 8e d8 |..df............|
000002c0 8e c0 8e d0 bc 00 01 a3 d8 82 89 26 00 80 8c c8 |...........&....|
000002d0 66 0f b7 c0 66 c1 e0 04 66 05 c0 82 00 00 a3 66 |f...f...f......f|
000002e0 7e 66 c1 e8 10 a2 68 7e 88 26 6b 7e 66 31 c0 8c |~f....h~.&k~f1..|
000002f0 c8 66 c1 e0 04 66 05 40 82 00 00 a3 5e 7e 66 c1 |.f...f.@....^~f.|
00000300 e8 10 a2 60 7e 88 26 63 7e 66 31 c0 8c c8 66 c1 |...`~.&c~f1...f.|
00000310 e0 04 66 05 a8 82 00 00 a3 6e 7e 66 c1 e8 10 a2 |..f......n~f....|
00000320 70 7e 88 26 73 7e 66 31 c0 8c d8 66 c1 e0 04 66 |p~.&s~f1...f...f|
00000330 05 00 80 00 00 a3 76 7e 66 c1 e8 10 a2 78 7e 88 |......v~f....x~.|
00000340 26 7b 7e 66 31 c0 8c d8 66 c1 e0 04 66 05 40 80 |&{~f1...f...f.@.|
00000350 00 00 a3 7e 7e 66 c1 e8 10 a2 80 7e 88 26 83 7e |...~~f.....~.&.~|
00000360 66 31 c0 8c d8 66 c1 e0 04 66 05 e0 82 00 00 a3 |f1...f...f......|
00000370 86 7e 66 c1 e8 10 a2 88 7e 88 26 8b 7e 66 31 c0 |.~f.....~.&.~f1.|
00000380 8c d8 66 c1 e0 04 66 05 00 83 00 00 a3 e2 82 66 |..f...f........f|
00000390 c1 e8 10 a2 e4 82 88 26 e7 82 66 31 c0 8c d8 66 |.......&..f1...f|
000003a0 c1 e0 04 66 05 4c 7e 00 00 66 a3 b5 7e 0f 01 16 |...f.L~..f..~...|
000003b0 b3 7e fa e4 92 0c 02 e6 92 0f 20 c0 66 83 c8 01 |.~........ .f...|
000003c0 0f 22 c0 66 ea 00 00 00 00 10 00 8c c8 8e d8 8e |.".f............|
000003d0 c0 8e d0 8b 26 00 80 e4 92 24 fd e6 92 fb b8 00 |....&....$......|
000003e0 4c cd 21 00 00 00 00 00 00 00 00 00 00 00 00 00 |L.!.............|
000003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000400 00 00 49 6e 20 50 72 6f 74 65 63 74 20 4d 6f 64 |..In Protect Mod|
00000410 65 20 6e 6f 77 2e 20 5e 2d 5e 00 41 42 43 44 45 |e now. ^-^.ABCDE|
00000420 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 |FGHIJKLMNOPQRSTU|
00000430 56 57 58 59 5a 00 00 00 00 00 00 00 00 00 00 00 |VWXYZ...........|
00000440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000005a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000005b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000005c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000005d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000005e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000005f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000640 66 b8 28 00 8e d8 66 b8 40 00 8e e8 66 b8 30 00 |f.(...f.@...f.0.|
00000650 8e d0 bc ff 01 00 00 b4 0c 31 f6 31 ff be 02 00 |.........1.1....|
00000660 00 00 bf 40 06 00 00 fc ac 84 c0 74 09 65 66 89 |...@.......t.ef.|
00000670 07 83 c7 02 eb f2 e8 15 00 00 00 9a 00 00 00 00 |................|
00000680 48 00 66 b8 38 00 0f 00 d0 ea 00 00 00 00 04 00 |H.f.8...........|
00000690 50 53 89 f8 b3 a0 f6 f3 25 ff 00 00 00 40 b3 a0 |PS......%....@..|
000006a0 f6 e3 89 c7 5b 58 c3 00 66 b8 40 00 8e e8 bf 80 |....[X..f.@.....|
000006b0 07 00 00 b4 0c b0 43 65 66 89 07 cb 00 00 00 00 |......Cef.......|
000006c0 b8 08 00 8e d8 8e c0 8e e0 8e e8 8e d0 0f 20 c0 |.............. .|
000006d0 24 fe 0f 22 c0 ea cb 7f 00 00 00 00 00 00 00 00 |$.."............|
000006e0 1a 00 00 00 00 98 40 00 00 00 00 00 00 00 00 00 |......@.........|
000006f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000700 66 b8 40 00 8e e8 bf 20 08 00 00 b4 0c b0 4c 65 |f.@.... ......Le|
00000710 66 89 07 f4 ea 00 00 00 00 18 00 |f..........|
0000071b
运行结果如下
根据运行结果可以看出,是如下代码的执行出现了问题
根据进一步的增加断点
运行结果如下所示
说明LABEL_DESC_NORMAL没有正确生成。
回过头来看,在《Orange S一个操作系统的实现》\chapter3\f\pmtest6.asm中第一次展示了开启分页,是需要着重研读的样本。源码如下:
; ==========================================
; pmtest6.asm
; 编译方法:nasm pmtest6.asm -o pmtest6.com
; ==========================================%include "pm.inc" ; 常量, 宏, 以及一些说明PageDirBase equ 200000h ; 页目录开始地址: 2M
PageTblBase equ 201000h ; 页表开始地址: 2M+4Korg 0100hjmp LABEL_BEGIN[SECTION .gdt]
; GDT
; 段基址, 段界限, 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW ; Normal 描述符
LABEL_DESC_PAGE_DIR: Descriptor PageDirBase, 4095, DA_DRW;Page Directory
LABEL_DESC_PAGE_TBL: Descriptor PageTblBase, 1023, DA_DRW|DA_LIMIT_4K;Page Tables
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32 ; 非一致代码段, 32
LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C ; 非一致代码段, 16
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW ; Data
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA + DA_32 ; Stack, 32 位
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限dd 0 ; GDT基地址; GDT 选择子
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT
SelectorPageDir equ LABEL_DESC_PAGE_DIR - LABEL_GDT
SelectorPageTbl equ LABEL_DESC_PAGE_TBL - LABEL_GDT
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt][SECTION .data1] ; 数据段
ALIGN 32
[BITS 32]
LABEL_DATA:
SPValueInRealMode dw 0
; 字符串
PMMessage: db "In Protect Mode now. ^-^", 0 ; 进入保护模式后显示此字符串
OffsetPMMessage equ PMMessage - $$
DataLen equ $ - LABEL_DATA
; END of [SECTION .data1]; 全局堆栈段
[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:times 512 db 0TopOfStack equ $ - LABEL_STACK - 1; END of [SECTION .gs][SECTION .s16]
[BITS 16]
LABEL_BEGIN:mov ax, csmov ds, axmov es, axmov ss, axmov sp, 0100hmov [LABEL_GO_BACK_TO_REAL+3], axmov [SPValueInRealMode], sp; 初始化 16 位代码段描述符mov ax, csmovzx eax, axshl eax, 4add eax, LABEL_SEG_CODE16mov word [LABEL_DESC_CODE16 + 2], axshr eax, 16mov byte [LABEL_DESC_CODE16 + 4], almov byte [LABEL_DESC_CODE16 + 7], ah; 初始化 32 位代码段描述符xor eax, eaxmov ax, csshl eax, 4add eax, LABEL_SEG_CODE32mov word [LABEL_DESC_CODE32 + 2], axshr eax, 16mov byte [LABEL_DESC_CODE32 + 4], almov byte [LABEL_DESC_CODE32 + 7], ah; 初始化数据段描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_DATAmov word [LABEL_DESC_DATA + 2], axshr eax, 16mov byte [LABEL_DESC_DATA + 4], almov byte [LABEL_DESC_DATA + 7], ah; 初始化堆栈段描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_STACKmov word [LABEL_DESC_STACK + 2], axshr eax, 16mov byte [LABEL_DESC_STACK + 4], almov byte [LABEL_DESC_STACK + 7], ah; 为加载 GDTR 作准备xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_GDT ; eax <- gdt 基地址mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址; 加载 GDTRlgdt [GdtPtr]; 关中断cli; 打开地址线A20in al, 92hor al, 00000010bout 92h, al; 准备切换到保护模式mov eax, cr0or eax, 1mov cr0, eax; 真正进入保护模式jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 处;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LABEL_REAL_ENTRY: ; 从保护模式跳回到实模式就到了这里mov ax, csmov ds, axmov es, axmov ss, axmov sp, [SPValueInRealMode]in al, 92h ; ┓and al, 11111101b ; ┣ 关闭 A20 地址线out 92h, al ; ┛sti ; 开中断mov ax, 4c00h ; ┓int 21h ; ┛回到 DOS
; END of [SECTION .s16][SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]LABEL_SEG_CODE32:call SetupPagingmov ax, SelectorDatamov ds, ax ; 数据段选择子mov ax, SelectorVideomov gs, ax ; 视频段选择子mov ax, SelectorStackmov ss, ax ; 堆栈段选择子mov esp, TopOfStack; 下面显示一个字符串mov ah, 0Ch ; 0000: 黑底 1100: 红字xor esi, esixor edi, edimov esi, OffsetPMMessage ; 源数据偏移mov edi, (80 * 10 + 0) * 2 ; 目的数据偏移。屏幕第 10 行, 第 0 列。cld
.1:lodsbtest al, aljz .2mov [gs:edi], axadd edi, 2jmp .1
.2: ; 显示完毕; 到此停止jmp SelectorCode16:0; 启动分页机制 --------------------------------------------------------------
SetupPaging:; 为简化处理, 所有线性地址对应相等的物理地址.; 首先初始化页目录mov ax, SelectorPageDir ; 此段首地址为 PageDirBasemov es, axmov ecx, 1024 ; 共 1K 个表项xor edi, edixor eax, eaxmov eax, PageTblBase | PG_P | PG_USU | PG_RWW
.1:stosdadd eax, 4096 ; 为了简化, 所有页表在内存中是连续的.loop .1; 再初始化所有页表 (1K 个, 4M 内存空间)mov ax, SelectorPageTbl ; 此段首地址为 PageTblBasemov es, axmov ecx, 1024 * 1024 ; 共 1M 个页表项, 也即有 1M 个页xor edi, edixor eax, eaxmov eax, PG_P | PG_USU | PG_RWW
.2:stosdadd eax, 4096 ; 每一页指向 4K 的空间loop .2mov eax, PageDirBasemov cr3, eaxmov eax, cr0or eax, 80000000hmov cr0, eaxjmp short .3
.3:nopret
; 分页机制启动完毕 ----------------------------------------------------------SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式
[SECTION .s16code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:; 跳回实模式:mov ax, SelectorNormalmov ds, axmov es, axmov fs, axmov gs, axmov ss, axmov eax, cr0and eax, 7FFFFFFEh ; PE=0, PG=0mov cr0, eaxLABEL_GO_BACK_TO_REAL:jmp 0:LABEL_REAL_ENTRY ; 段地址会在程序开始处被设置成正确的值Code16Len equ $ - LABEL_SEG_CODE16; END of [SECTION .s16code]
【日拱一卒行而不辍20220925】自制操作系统相关推荐
- 【日拱一卒行而不辍20220926】自制操作系统
分页原理 在汇编文件chapter3/f/pmtest6.asm中,关于分页设置的代码如下. 此时还未开启多进程,仅有的一个进程中这个表有什么作用吗?页表需要进行切换吗? 每一个进程都会形成这样一个完 ...
- 【日拱一卒行而不辍20220921】自制操作系统
8086内存安排 8086实模式的寻址范围只有1MB.其中: 系统硬件使用的存储器地址被安排在高端,地址从0xA0000H(684KB)开始的384KB中,其中有用于显示的视频缓冲区: 内存低端安排了 ...
- 【日拱一卒行而不辍20221010】自制操作系统
多进程 修改后的如下chapter6E的Makefile如下所示如下 ######################### # Makefile for Orange'S # ############# ...
- 【日拱一卒行而不辍20220924】自制操作系统
8086内存地址变换过程 80x86在从逻辑地址到物理地址变换过程中使用了分段和分页二种机制. 第一阶段使用分段机制将程序的逻辑地址变换成可寻址内存空间的线性地址. 第二阶段用分页机制把线性地址转换成 ...
- 日拱一卒,功不唐捐 | 每日思考俱乐部 专栏更新通知
缘起 在 2019 年七月份,我写了一篇文章<我为什么要写反思录>.文中提到了我做记录和思考的初衷,起初写在了自己的私密仓库中,也就是其他人都看不到. 持续了一段时间后,我发现,没有分享的 ...
- 日拱一卒,“功不唐捐
据说,世界上只有两种动物能够登上金字塔顶,一种是老鹰,一种是蜗牛.他们是如此不同,老鹰矫健,敏捷,蜗牛弱小,迟钝,可是蜗牛仍然与老鹰一样能达到金字塔顶端.它凭的就是永不停息的执着精神. "日 ...
- 社区人物志|李昊鹏:日拱一卒,功不唐捐
「社区人物志」是 Apache Doris 社区推出的系列专栏,我们关注每一个对 Doris 做出过贡献的 Contributor ,会定期从对 Doris 做出突出贡献的小伙伴中选出一位「社区之星」 ...
- #研发解决方案#大数据协作平台魔盒——日拱一卒,功不唐捐
郑昀 创建于2017/6/29 最后更新于2017/6/30 关键词:大数据,Spark,SparkSQL,HBase,HDFS,工作流,任务,Flow,Job,监控报警 提纲: 为什么要大数据协作? ...
- 日拱一卒,集小胜为大胜; 学以致用,在战争中学习战争;
项目,证明自己的学习能力: 短期掌握尽可能多的知识,并且连线总结成为网络 : 日拱一卒,集小胜为大胜: 学以致用,在战争中学习战争: 投入足够的时间: 学习中的总结,理解 ,应用,等编程套路: 目的性 ...
最新文章
- php数组的奇数_用php输出一个数组中的偶数或奇数的方法
- 十大开源推荐系统简介 [转自oschina]
- 【大话Hibernate】hibernate事务管理
- 不能以根用户身份运行 Google Chrome 浏览器
- Linux系统:centos7下搭建ElasticSearch中间件,常用接口演示
- IOS 文本文字下面添加下划线
- 如何将CSS3 transforms应用于背景图像
- 中移4G模块-ML302-OpenCpu开发-GPIO
- Linux运维问题解决(3)——VMware启动虚拟机报错 : 该虚拟机似乎正在使用中。如果该虚拟机未在使用,请按“获取(T)
- Python入门--else语句
- 性能计数器驱动_Vulkan 探密:AMD Vulkan 开源驱动源码解析-零
- 学习笔记-Map集合的遍历
- Python 文本滚动播放
- linux安装有道词典步骤,Ubuntu 16.04安装有道词典的方法
- C#VS2019中ReportViewer控件和报表设计器 RDLC使用方法总结
- C语言程序设计——从入门到进阶,C语言程序设计——从入门到进阶-巨同升主编.pdf(3)...
- 某人将1000元存入银行 某公司需用一台设备 某企业为了建一项目 建设期3年,共贷款700万元
- 【windows版本】 db2数据库安装与使用
- C++ std::multiset返回值 has no member named ‘first’
- 1244 数列有序
热门文章
- 4-springcloud负载均衡( ribbon )案例
- 小程序代码反编译获取小程序源码nodejs
- 【技术变现小技巧】-- Boss直聘 批量打招呼
- 16、配置路由器的动态路由(OSPF协议)
- 自建Binlog订阅服务 —— Maxwell
- SD+PP+MM+FICO+HR概述
- js 延迟执行php代码,jquery如何实现延迟执行
- vue中axios改变header为application/x-www-form-urlencoded不起作用
- hihocoder #1179 : 永恒游戏 暴力
- 2022中国绿色资本市场绿皮书