参考:
https://blog.csdn.net/tyler_download/article/details/52242599
DOS是实模式,20位总线,1M内存。体验不好。寄存器也是16位的。90年代用dos编程,竟然也有WPS这样的神作,真是佩服求伯君。
windows是保护模式,32位总线。4G内存,80386是经典,win95也是经典。
保护模式不再直接寻址,而是用GDT获取描述符,描述符中再计算地址。
进入保护模式一个巨大好处是可以引入C语言。
本次实验就是把数据写入内存5M位置,然后在从这个位置读取数据显示出来,体现寻址5M的能力。
boot_read5M.asm
比上节GDT表中增加了LABEl_DESC_5M这样一个段,基地址0500000h,也就是5M的位置。
selector_5M是这个段离表头的偏移。
es指向selector_5M,也就是5M的基地址,es:edi循环写入字符串msg。
然后显示msg: [es:si]是5M基地址,到[gs:edi]显存。
编译:nasm -o boot.bat boot_read5M.asm
使用上几节的OpSystem.java类,这个只写了第一个引导扇区,其他扇区写了个字符串,不影响,可直接使用这个工具做system.img
加载到virtualbox 运行成功:
boot_read5M.asm
%include "pm.inc"
org 0x7c00
jmp LABEL_BEGIN
[SECTION .gdt]
LABEL_GDT: Descriptor 0, 0, 0
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW
LABEL_DESC_5M: Descriptor 0500000h, 0ffffh, DA_DRW
GdtLen equ $ - LABEL_GDT
GdtPtr dw GdtLen - 1
dd 0
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
Selector5M equ LABEL_DESC_5M - LABEL_GDT
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
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
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT
mov dword [GdtPtr + 2], eax
lgdt [GdtPtr]
cli
in al, 92h
or al, 00000010b
out 92h, al
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword SelectorCode32: 0
[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorVideo
mov gs, ax
mov si, msg
mov ax, Selector5M
mov es, ax
mov edi, 0
write_msg_to_5M:
cmp byte[si], 0
je prepare_to_show_char
mov al, [si]
mov [es:edi], al
add edi, 1
add si, 1
jmp write_msg_to_5M
prepare_to_show_char:
mov ebx,10
mov ecx, 2
mov si, 0
showChar:
mov edi, (80*11)
add edi, ebx
mov eax, edi
mul ecx
mov edi, eax
mov ah, 0ch
mov al, [es:si]
cmp al, 0
je end
add ebx, 1
add si, 1
mov [gs:edi], ax
jmp showChar
end:
jmp $
msg:
DB "This string is written to 5M memroy", 0
SegCode32Len equ $ - LABEL_SEG_CODE32