我正在继续调查 BIOS 16-32 任务的概念验证。之前我的帖子研究了保护模式和 BIOS 之间任务分配的常规方法,以及在此链接上找到的基本 16 <-> 32 任务方法16 到 32 保护模式 BIOS 任务分配的概念证明
现在我的代码的最新测试显示 BIOS 任务段内的 jmp-if 条件满足结构之间存在差异。为了总结这里的测试,问题出现在键盘输入控制器代码的第二个标签上,该代码从键码。但是,该结构在程序的第二个标记实例 (SetOn:) 上失败。可以通过取消注释实例变量来验证此观察结果。就像在我添加我的源代码之前一样,希望能澄清这种差异,并且真的很乐意对此进行更多研究。
stage1.asm
; ReTimerOS
; Copyright (C) 2022,2023 Christopher Hoy
;
; This file is part of ReTimerOS
; ReTimerOS is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
;[ORG 0x7E00]
%define BUILD_GDT_DESC(bounds,base,access,flags) \
((( base & 0x00FFFFFF) << 16) | \
(( base & 0xFF000000) << 32) | \
( bounds & 0x0000FFFF) | \
(( bounds & 0x000F0000) << 32) | \
(( access & 0xFF) << 40) | \
(( flags & 0x0F) << 52))
TSS_IO_MAP_SIZE EQU 0x400/8
%define REBASE_ADDRESS(A) (0x7E00 + ((A) - BIOS32_PREP))
[BITS 16]
section .data
ROWS EQU 25
COLS1 EQU 80
section .text
_prep_module2:
; jmp _prep_module2_
;[bits 32]
BIOS32_PREP:use32
pusha
;pushf
; save current esp to edx
mov edx, esp
; jumping to 16 bit protected mode
; disable interrupts
cli
; clear cr3 by saving cr3 data in ebx register
xor ecx, ecx
mov ebx, cr3
mov cr3, ecx
; load new empty GDT
lgdt [REBASE_ADDRESS(bios32_gdt_ptr)]
; lgdt [REBASE_ADDRESS(gdt32Ptr)]
; load new empty IDT
lidt [REBASE_ADDRESS(bios32_idt_ptr)]
; jump to 16 bit protected mode
jmp 0x30:REBASE_ADDRESS(__protected_mode_16)
; jmp code16_post:REBASE_ADDRESS(__protected_mode_16)
;[bits 16]
; 16 bit protected mode
__protected_mode_16:use16
; jumping to 16 bit real mode
mov ax, 0x38
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; turn off protected mode
; set bit 0 to 0
mov eax, cr0
and al, ~0x01
mov cr0, eax
jmp 0x0:REBASE_ADDRESS(__real_mode_16)
; 16 bit real mode
__real_mode_16:use16
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov sp, 0x8c00
; enable bios interrupts to call
sti
; save current context, all general, segment registers, flags
pusha
mov cx, ss
push cx
mov cx, gs
push cx
mov cx, fs
push cx
mov cx, es
push cx
mov cx, ds
push cx
pushf
; get current stack pointer & save it to current_esp
mov ax, sp
mov edi, current_esp
stosw
; load our custom registers context
mov esp, REBASE_ADDRESS(bios32_in_reg16_ptr)
; only use some general register from the given context
popa
; set a new stack for bios interrupt
mov sp, 0x9c00
; call immediate interrupt opcode to execute context
pusha
; mov dx,sp
; jmp GraphicCtrlA
jmp short bios32_GraphicCtrlA
bios32_GraphicCtrlA:
; will be bios interrupt number passed
; put the actual interrupt number here
; db 0xCD
; db 0x10
; db 0x01
mov ax,0x13
int 0x10
;graphic_function2:
; call bios32_int_number_ptr
mov dh,1
mov dl,1
call GraphicPrint
; jmp loopstep1
; popa
; mov ax,0x13
; int 0x10
loopstep1:
mov ah,01h
int 16h
jz loopstep1
call GraphicPrint
mov ah,00h
int 16h
cmp ah,48h
jnz SetOn
cmp dl,0
jz SetOn
dec dl
SetOn:
cmp ah,50h
; jnz short SetOff
cmp dl,24
; jz short SetOff
inc dl
SetOff:
cmp ah,48h
; jnz SetNotLeft
cmp dh,0
; jz SetNotLeft
dec dh
SetNotLeft:
cmp ah,4Dh
; jnz SetNotRight
cmp dh,39
; jz SetNotRight
inc dh
SetNotRight:
call GraphicPrint
jmp loopstep1
popa
jmp $
; jmp poll_function
GraphicPrint:
mov cx,0A000h
mov es,cx
; mov ax
push dx
mov ax,8
mul dh
mov bp,ax
mov ax,8*320
mov bx,0
add bl,dl
mul bx
add bp,ax
pop dx
mov si,GraphicA
mov cl,8
PrintGraphicY:
push bp
mov ch,8
PrintGraphicX:
mov al,[ds:si]
xor al,[es:bp]
mov [es:bp],al
inc si
inc bp
dec ch
jnz PrintGraphicX
pop bp
add bp,320
dec cl
jnz PrintGraphicY
; mov sp,dx
;GraphicCtrlRet:
hlt
; popa
ret
; jmp poll_function
; jmp GraphicCtrlRet
; ret
GraphicA:
db 00h,00h,0Eh,0Eh,0Eh,0Eh,00h,00h
db 00h,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,00h
db 0Eh,0Eh,05h,0Eh,0Eh,05h,0Eh,0Eh
db 0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh
db 0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh
db 0Eh,0Eh,04h,0Eh,0Eh,04h,0Eh,0Eh
db 00h,0Eh,0Eh,04h,04h,0Eh,0Eh,00h
db 00h,00h,0Eh,0Eh,0Eh,0Eh,00h,00h
poll_function:
; get our output context here
mov esp, REBASE_ADDRESS(bios32_out_reg16_ptr)
add sp, 28 ; restore stack used for calling our context
; save current context, all general, segment registers, flags
pushf
mov cx, ss
push cx
mov cx, gs
push cx
mov cx, fs
push cx
mov cx, es
push cx
mov cx, ds
push cx
pusha
; restore the current_esp to continue
mov esi, current_esp
lodsw
mov sp, ax
; restore all current context, all general, segment registers, flags
popf
pop cx
mov ds, cx
pop cx
mov es, cx
pop cx
mov fs, cx
pop cx
mov gs, cx
pop cx
mov ss, cx
popa
; jmp _prep_module2_
; jumping to 32 bit protected mode
; set bit 0 in cr0 to 1
;testGate:
lgdt[gdt32Ptr]
; lgdt [REBASE_ADDRESS(bios32_gdt_ptr)]
mov eax, cr0
; inc eax
or eax,1
mov cr0, eax
; smsw eax
; jmp 0x08:REBASE_ADDRESS(__protected_mode_32)
; jmp 0x10:REBASE_ADDRESS(__protected_mode_32)
_prep_module2_:
cld
cli
in al,0x92
or al,2
out 0x92,al
; mov [saved_segment],ds
; lidt[Idtpipe32]
; jmp code32_post:REBASE_ADDRESS(__protected_mode_32)
jmp code32_post:__protected_mode_32
; jmp 0x08:__protected_mode_32
; jmp 0x10:__protected_mode_32
; jmp 0x08:REBASE_ADDRESS(__protected_mode_32)
; jmp 0x10:REBASE_ADDRESS(__protected_mode_32)
[bits 32]
; 32 bit protected mode
__protected_mode_32:use32
; mov ax, 0x10
mov ax,data32_post
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; mov ss, ax
; restore cr3
mov cr3, ebx
; restore esp
mov esp, edx
; sti
popa
; hlt
; jmp _BIOS32_PREP
; jmp code16_post:REBASE_ADDRESS(__protected_mode_32)
;use16
; jmp code16_post:REBASE_ADDRESS(BIOS32_PREP)
; lgdt [REBASE_ADDRESS(bios32_gdt_ptr)]
; jmp 0x30:REBASE_ADDRESS(__protected_mode_16)
jmp $
.loopcheck:
hlt
jmp .loopcheck
__padding:
db 0x0
db 0x0
db 0x0
bios32_gdt_entries:
; 8 gdt entries
resb 64
bios32_gdt_ptr:
dd 0x00000000
dd 0x00000000
bios32_idt_ptr:
dd 0x00000000
dd 0x00000000
bios32_in_reg16_ptr:
resw 14
bios32_out_reg16_ptr:
dd 0xaaaaaaaa
dd 0xaaaaaaaa
dd 0xaaaaaaaa
dd 0xaaaaaaaa
dd 0xaaaaaaaa
dd 0xaaaaaaaa
dd 0xaaaaaaaa
current_esp:
dw 0x0000
section .data
gdt32:
dq BUILD_GDT_DESC(0,0,0,0)
gdt32code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1100b)
gdt32data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1100b)
gdt16code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1000b)
gdt16data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1000b)
;gdt16tss:dq BUILD_GDT_DESC(0x8230,TSS_SIZE-1,10001001b,0000b) & 0 << 22
gdt32tss:
dq BUILD_GDT_DESC(TSS_SIZE-1,0x8280,10001001b,0000b)
; dq BUILD_GDT_DESC(TSS_SIZE-1,0x9260,10001001b,0000b)
.stub1:
code32_post: equ gdt32code -gdt32
data32_post: equ gdt32data -gdt32
;.stub:
code16_post: equ gdt16code -gdt32
data16_post: equ gdt16data -gdt32
tss32_post: equ gdt32tss -gdt32
gdt32Len: equ $-gdt32
gdt32Ptr: dw gdt32Len-1
dd gdt32
align 4
;vidmem_ptr: dd VIDEO_TEXT_ADDR
pm_str: db 'protected mode string ',0
pm_str_length: equ $-pm_str
vm_str: db 'virtual',0
;vidmem_address: dw 0
;resb 512
times 512 db 0
align 16
tss:
.back_link: dd 0
.esp0: dd 0
.ss0: dd 0
.esp1: dd 0
.ss1: dd 0
.esp2: dd 0
.ss2: dd 0
.cr3: dd 0
.eip: dd 0
.eflags: dd 0
.eax: dd 0
.ecx: dd 0
.edx: dd 0
.ebx: dd 0
.esp: dd 0
.ebp: dd 0
.esi: dd 0
.type2: dd 0
.es: dd 0
.cs: dd 0
.ss: dd 0
.ds: dd 0
.fs: dd 0
.gs: dd 0
.ldt: dd 0
.trap: dw 0
.iomap_base: dw 0
.iomap: TIMES TSS_IO_MAP_SIZE db 0x00
%if TSS_IO_MAP_SIZE > 0
.iomap_pad:db 0xff
%endif
.end:
TSS_SIZE: EQU tss.end -tss
align 4
ColorTable: db 00h,01h,02h,03h,04h,05h,06h,07h
;db 10h,11h,12h,13h,14h,15h,16h,17h
db 38h,39h,3Ah,3Bh,3Ch,3Dh,3Eh,3Fh
ColorTableSize: equ $-ColorTable
save_cr0 dd 0
save_cr3 dd 0
saved_segment resd 0
gate_voucher dw 1
;X dd 0
;Y dd 0
;color_pkg dw 5
section .bss
align 16
;ring0_proc_stack: resb RING0_PROC_STACK_SIZE
ring0_proc_stack_placer:
align 4
save_esp: resd 1
save_ss: resd 1
;rm_poll_prep:
; mov cx,gdt16data
; xor ecx,ecx
; mov ds,cx
; mov es,cx
; mov gs,cx
; mov fs,cx
; mov cs,gdt16code
; mov ds,gdt16data
; lgdt[gdt16Ptr]
; lidt[Idtpipe]
; sti
; jmp $
; jmp color_function
;._prep_stage:
; mov dword [tss.ss],VM_STACK_SEG
; mov dword [tss.esp],VM_STACK_OFS
; mov dword [tss.eflags],1 << FLAGS_VM_CMP | 1 << FLAGS_CMP1
; mov dword [tss.cs],VM_CS_SEG
; mov dword [tss.eip],vm_module
;prep_stage4:
; mov si,0
; mov ds,si
; push ds
; push ds
; push ds
; push ds
; push VM_STACK_SEG
; push VM_STACK_OFS
; push dword 1 << FLAGS_VM_CMP
; push dword 1 << FLAGS_VM_CMP | 1 << FLAGS_CMP1
; push dword 1 << FLAGS_VM_CMP | 1 << FLAGS_CMP1 | 2 << FLAGS_CMP_IOPL
; push dword 1 << FLAGS_VM_CMP | 1 << FLAGS_CMP1 | 2 << FLAGS_CMP_IOPL | 1 << FLAGS_CMP_IF
; push VM_CS_SEG
; push vm_module
; iret
;poll_function1:
;.prep:
; xor ebx,ebx
; xor edx,edx
; mov ax,0
; mov cx,0
; mov es,cx
; mov ax,ROWS
; mov bx,es:0x044A
; mul bx
; add ax,COLS1
; shl ax,1
; mov si,ax
; mov cx,0B000H
; test byte es:0x0410,2
; jnz .Address_OK
; mov cx,0B800H
;.Address_OK:
; mov es,cx
; mov al,'H'
; mov es:[si],byte al
; mov es:0,byte al
; mov es:si,byte al
; mov ds:si,byte al
; mov ds:[si],byte al
; inc si
; ret
;use16
;[bits 16]
;task_poke16:
; mov dword [tss.eip],ecx
; mov dword [tss.eflags]
; mov ax,[tss.eax]
; mov cx,[tss.ecx]
; mov dx,[tss.edx]
; mov bx,[tss.ebx]
; mov sp,[tss.esp]
; mov bp,[tss.ebp]
; mov si,[tss.esi]
; mov di,[tss.type2]
; mov cx,[tss.ds]
; mov es,cx
; mov ss,cx
; mov ds,cx
; mov fs,cx
; mov gs,cx
boot.asm
; ReTimerOS
; Copyright (C) 2022,2023 Christopher Hoy
;
; This file is part of ReTimerOS
; ReTimerOS is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
[BITS 16]
;[ORG 0x7c00]
section .text
_prep_module:
xor ax,ax
mov ds,ax
mov es,ax
mov ss,ax
; mov sp,0x7c00
mov sp,0x9000
DriveIdPrep:
mov [DriveId],dl
mov ah,0x41
mov bx,0x55aa
int 0x13
; jc CheckPrep
cmp bx,0xaa55
; jne CheckPrep
SizeFunction:
mov bx,0x0000_7E00
mov cl,2
mov ah,0x02
; mov al,1
mov al,5
mov ch,0
mov dh,0
int 0x13
; jc ReadCheck
mov dl,[DriveId]
; mov si,[String1]
jmp 0x7e00
; call prototype3
; call main
; jmp $
Section .data
DriveId: db 0
String: db "Check",0
MessageLen: equ $-String
ReadPacket: times 16 db 0
ColorTable: db 00h,01h,02h,03h,04h,05h,06h,07h
;db 10h,11h,12h,13h,14h,15h,16h,17h
db 38h,39h,3Ah,3Bh,3Ch,3Dh,3Eh,3Fh
ColorTableSize: equ $-ColorTable
ROWS EQU 25
COLS1 EQU 80
BACK1 EQU 05h
FRONT1 EQU 12h
CHECKER EQU 0
;Graphics_CTRLA EQU 0x03CE
;Sequencer_CTRLA EQU 0x03C4
Graphics_CTRLA EQU 03CEh
Sequencer_CTRLA EQU 03C4h
Crd1Size EQU 640
HDATA EQU (Crd1Size/8)
Graph_Segment EQU 0A000H
;HDATA EQU (crd2+crd1/8)
;Crd1 EQU [bp+4]
;Crd2 EQU [bp+6]
;Color EQU [bp+8]
crd1 EQU 45
crd2 EQU 54
color EQU 05h
X dd 0
Y dd 0
color_pkg dw 0x05
LoopVar1: db 0
;LoopVar EQU [LoopVar1]
;ROWS EQU 0x18
;COLS1 EQU 0x4F
;ROWS: db 20
;COLS1: db 80
Value1: db 0
生成文件```
FILES =boot.o printstr.o
PROCURE = rm -rf
all: boot.bin stage1.bin
dd if=boot.bin of=os.img bs=512 count=1 conv=notrunc
dd if=stage1.bin of=os.img bs=512 count=3 seek=1 conv=notrunc
boot.o: boot.asm
nasm -f elf -g -o boot.o boot.asm
printstr.o: printstr.asm
nasm -f elf -g -o printstr.o printstr.asm
stage1.o: stage1.asm
nasm -f elf -g stage1.asm -o stage1.o
boot.bin: $(FILES)
ld -T link.ld $(FILES) -o boot.bin
stage1.bin: stage1.o
ld -g -m elf_i386 -T link2.ld stage1.o -o stage1.bin --oformat binary
clean:
$(PROCURE) */.o
$(PROCURE) */.bin
$(PROCURE) os.img
``
printstr.asm
bits 16
global printstr
printstr:
lodsb
test al,al
jz .done
mov ah,0x0E
mov bx,7
int 0x10
jmp printstr
.done:
ret
干杯!