rem auto.cmd
@echo off
nasm -fbin -o boot.bin boot.asm
dd if=boot.bin of=c.img seek=0 count=1
echo.
nasm -fbin -o loader.bin loader.asm
dd if=loader.bin of=c.img seek=1 count=20
echo.
nasm -fbin -o kernel.bin kernel.asm
dd if=kernel.bin of=c.img seek=21 count=8192
echo.
del c.img.lock
pause
; boot.asm
bits 16
start:
cli
mov ax, 0x7c0
mov ds, ax
mov dx, 0x1f2
mov al, 20
out dx, al
mov dx, 0x1f3
mov al, 1
out dx, al
mov dx, 0x1f4
mov al, 0
out dx, al
mov dx, 0x1f5
mov al, 0
out dx, al
mov dx, 0x1f6
mov al, 0xe0
out dx, al
mov dx, 0x1f7
mov al, 0x20
out dx, al
mov dx, 0x1f7
.1:
in al, dx
and al, 0x88
cmp al, 0x08
jnz .1
mov cx, 20 * 256
mov bx, 0x200
mov dx, 0x1f0
.2:
in ax, dx
mov [bx], ax
inc bx
inc bx
loop .2
lgdt [gdtr]
in al, 0x92
or al, 0x2
out 0x92, al
mov eax, cr0
or al, 0x1
mov cr0, eax
jmp dword 1 * 8 : 0
gdt_start:
dq 0x0000_0000_0000_0000 ; 0 * 8
dq 0x00cf_9a00_7e00_ffff ; 1 * 8
dq 0x00cf_9200_7e00_ffff ; 2 * 8
dq 0x00cf_920b_8000_ffff ; 3 * 8
dq 0x00cf_9a00_0000_ffff ; 4 * 8
dq 0x00cf_9200_0000_ffff ; 5 * 8
gdt_end:
gdtr:
dw gdt_end - gdt_start - 1
dd 0x7c00 + gdt_start
times 512 - 2 - ($ - $$) db 0
dw 0xaa55
; loader.asm
bits 32
start:
mov ax, 3 * 8
mov gs, ax
mov ax, 2 * 8
mov ds, ax
mov ss, ax
mov esp, stack_top
; 开辟栈空间
sub esp, 20 * 4
; call cls
; xor ebx, ebx
; mov byte [gs: ebx], 'P'
; inc ebx
; mov byte [gs: ebx], 0xc
; inc ebx
mov dword [esp + 0 * 4], 21
mov dword [esp + 1 * 4], 8192
mov dword [esp + 2 * 4], 0x100000
call load_hd_to_mem
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 0
mov dword [esp + 2 * 4], 0
mov dword [esp + 3 * 4], 0
mov dword [esp + 4 * 4], 0
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 1
mov dword [esp + 2 * 4], 0x100000
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x9a + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 2
mov dword [esp + 2 * 4], 0x100000
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x92 + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 3
mov dword [esp + 2 * 4], 0xb8000
mov dword [esp + 3 * 4], 0x00000fff
mov dword [esp + 4 * 4], 0x92 + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 4
mov dword [esp + 2 * 4], 0
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x9a + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 5
mov dword [esp + 2 * 4], 0
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x92 + 0xc000
call create_descriptor
;加载全局描述符表
lgdt [gdtr]
lidt [idtr]
;释放预留的栈空间
add esp, 20 * 4
;长跳入至内核开始处,即是0x100000开始的段
jmp dword 1 * 8 : 0
%include "syslib.asm" ;描述符填充函数所在的文件
stack_bottom:
times 1024 db 0
stack_top: ;栈顶
gdtr: ;全局描述符表寄存器将从内存的此处加载全局描述符表的首地址和段限长
;这是一个6字节长度的数据结构,低两个字节为段限长,高四个字节为描述表物理基地址
;因此全局描述符表最多 2^16 / 8个描述符,即8192个,(每个描述符长8个字节)
dw 256 * 8 - 1
dd 0x7c00 ;描述表的基地址定在了此处,也就覆盖了引导扇区和加载程序
idtr:
dw 256 * 8 - 1
dd 0
; kernel.asm
bits 32
start:
mov ax, 3 * 8
mov gs, ax
mov ax, 2 * 8
mov ds, ax
mov es, ax
mov fs, ax
mov ss, ax
mov esp, stack_top
sub esp, 50 * 4
call cls
; call set_page
call init_idt
call init_8259
call init_8254
call init_rtc
mov al, 1111_1000b ; only open clock interrupt
out 0x21, al
mov al, 1111_1110b
out 0xa1, al
call init_process
add dword [process_table_point], 0 * 36 * 4
call re_start
add esp, 50 * 4
.loop:
sub esp, 50 * 4
hlt
add esp, 50 * 4
jmp .loop
align 4 * 1024
stack_bottom:
times 4 * 1024 db 0
stack_top:
align 4096
page_dir_start:
times 4096 db 0
page_dir_end:
PAGE_DIR_BASE equ 0x100000 + page_dir_start
page_table_start:
times 8 * 4096 db 0
page_table_end:
PAGE_TABLE_BASE equ 0x100000 + page_table_start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include "syslib.asm"
;;;;;process schedule;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
init_process:
enter
pusha
sub esp, 20 * 4
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 20
mov dword [esp + 2 * 4], 0x100000 + tss_start
mov dword [esp + 3 * 4], tss_end - tss_start + 1
mov dword [esp + 4 * 4], 0x89 ; task status segment
call create_descriptor
mov dword [tss_start + tss.ss0], 2 * 8
mov word [tss_start + tss.iobase], tss_end - tss_start - 1
mov ax, 20 * 8
ltr ax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 21
mov dword [esp + 2 * 4], 0x100000 + 0 * 36 * 4 + process_table_start + process_control.ldt
mov dword [esp + 3 * 4], ldt_size * u64 - 1
mov dword [esp + 4 * 4], 0x82 ; locak descriptor
call create_descriptor
mov dword [esp + 0 * 4], 0x100000 + 0 * 36 * 4 + process_table_start + process_control.ldt
mov dword [esp + 1 * 4], 1 ; 第2个描述符,从0开始,第1个没有用
mov dword [esp + 2 * 4], 0x100000 ;任务代码的首物理地址
mov dword [esp + 3 * 4], 0xfffff ;任务的段长度
mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x20 ; 0x9a:存在的可执行可读代码段
call create_descriptor ; 0xc0:粒度为4k, 使用32位地址及32位或8位操作数
mov dword [esp + 0 * 4], 0x100000 + 0 * 36 * 4 + process_table_start + process_control.ldt ;局部描述符表的首物理地址
mov dword [esp + 1 * 4], 2 ; 第3个描述符,从0开始
mov dword [esp + 2 * 4], 0x100000 ;和任务共用一个段
mov dword [esp + 3 * 4], 0xfffff;因此数据段和代码段使用相同的物理地址
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ; 0x9a:存在的可读可写数据段
call create_descriptor ; 0xc0:粒度为4k, 段的上部界限为4G
; 0x20:DPL--描述符特权级为1 ; 0x20:DPL--描述符特权级为1
mov dword [esp + 0 * 4], 0x100000 + 0 * 36 * 4 + process_table_start + process_control.ldt ;局部描述符表的首物理地址
mov dword [esp + 1 * 4], 3 ; 第4个描述符,从0开始
mov dword [esp + 2 * 4], 0xb8000 ;显存段的起始地址
mov dword [esp + 3 * 4], 0xfffff ; 段限长为0xfff * 4k
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ; 0x9a:存在的可读可写数据段
call create_descriptor ; 0xc0:粒度为4k, 段的上部界限为4G
; 0x20:DPL--描述符特权级为1
mov dword [process_table_start + process_control.ldt_sel], 21 * 8
mov dword [process_table_start + process_stack.gs], 3 * 8 + 5
mov dword [process_table_start + process_stack.fs], 2 * 8 + 5
mov dword [process_table_start + process_stack.es], 2 * 8 + 5
mov dword [process_table_start + process_stack.ss], 2 * 8 + 5
mov dword [process_table_start + process_stack.ds], 2 * 8 + 5
mov dword [process_table_start + process_stack.cs], 1 * 8 + 5
mov dword [process_table_start + process_stack.eip], function1_start
mov dword [process_table_start + process_stack.esp], task_or_user_stack_top
mov dword [process_table_start + process_stack.eflags], 0x1202
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov edx, process_table_start + 1 * 36 * 4
mov ecx, 2
mov eax, 1
.1:
mov dword [esp + 0 * 4], 0x7c00
mov ebx, 21
add ebx, eax
mov dword [esp + 1 * 4], ebx
push eax
push edx
xor edx, edx
mov ebx, 36 * 4
mul ebx
mov ebx, 0x100000 + process_table_start + process_control.ldt
add ebx, eax
pop edx
pop eax
mov dword [esp + 2 * 4], ebx
mov dword [esp + 3 * 4], ldt_size * u64 - 1
mov dword [esp + 4 * 4], 0x82 ; locak descriptor
call create_descriptor
mov dword [esp + 0 * 4], ebx
mov dword [esp + 1 * 4], 1 ; 第2个描述符,从0开始,第1个没有用
mov dword [esp + 2 * 4], 0x100000 ;任务代码的首物理地址
mov dword [esp + 3 * 4], 0xfffff ;任务的段长度
mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x20 ; 0x9a:存在的可执行可读代码段
call create_descriptor ; 0xc0:粒度为4k, 使用32位地址及32位或8位操作数
mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
mov dword [esp + 1 * 4], 2 ; 第3个描述符,从0开始
mov dword [esp + 2 * 4], 0x100000 ;和任务共用一个段
mov dword [esp + 3 * 4], 0xfffff;因此数据段和代码段使用相同的物理地址
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ; 0x9a:存在的可读可写数据段
call create_descriptor ; 0xc0:粒度为4k, 段的上部界限为4G
; 0x20:DPL--描述符特权级为1 ; 0x20:DPL--描述符特权级为1
mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
mov dword [esp + 1 * 4], 3 ; 第4个描述符,从0开始
mov dword [esp + 2 * 4], 0xb8000 ;显存段的起始地址
mov dword [esp + 3 * 4], 0xfffff ; 段限长为0xfff * 4k
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ; 0x9a:存在的可读可写数据段
call create_descriptor ; 0xc0:粒度为4k, 段的上部界限为4G
; 0x20:DPL--描述符特权级为1
sub ebx, process_control.ldt + 0x100000
mov edx, ebx
mov ebx, 21
add ebx, eax
shl ebx, 3
mov dword [edx + process_control.ldt_sel], ebx
mov dword [edx + process_stack.gs], 3 * 8 + 5
mov dword [edx + process_stack.fs], 2 * 8 + 5
mov dword [edx + process_stack.es], 2 * 8 + 5
mov dword [edx + process_stack.ss], 2 * 8 + 5
mov dword [edx + process_stack.ds], 2 * 8 + 5
mov dword [edx + process_stack.cs], 1 * 8 + 5
mov dword [edx + process_stack.eflags], 0x1202
mov esi, function_point
mov ebx, eax
shl ebx, 2
add esi, ebx
mov ebx, [esi]
mov dword [edx + process_stack.eip], ebx
mov esi, task_or_user_stack_top
mov ebx, eax
shl ebx, 9
sub esi, ebx
mov dword [edx + process_stack.esp], esi
inc eax
dec ecx
cmp ecx, 0
jne .1
mov edx, process_table_start + 3 * 36 * 4
mov ecx, 3
mov eax, 3
.2:
mov dword [esp + 0 * 4], 0x7c00
mov ebx, 21
add ebx, eax
mov dword [esp + 1 * 4], ebx
push eax
push edx
xor edx, edx
mov ebx, 36 * 4
mul ebx
mov ebx, 0x100000 + process_table_start + process_control.ldt
add ebx, eax
pop edx
pop eax
mov dword [esp + 2 * 4], ebx
mov dword [esp + 3 * 4], ldt_size * u64 - 1
mov dword [esp + 4 * 4], 0x82 ; locak descriptor
call create_descriptor
mov dword [esp + 0 * 4], ebx
mov dword [esp + 1 * 4], 1 ; 第2个描述符,从0开始,第1个没有用
mov dword [esp + 2 * 4], 0x100000 ;任务代码的首物理地址
mov dword [esp + 3 * 4], 0xfffff ;任务的段长度
mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x60 ; 0x9a:存在的可执行可读代码段
call create_descriptor ; 0xc0:粒度为4k, 使用32位地址及32位或8位操作数
mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
mov dword [esp + 1 * 4], 2 ; 第3个描述符,从0开始
mov dword [esp + 2 * 4], 0x100000 ;和任务共用一个段
mov dword [esp + 3 * 4], 0xfffff;因此数据段和代码段使用相同的物理地址
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60 ; 0x9a:存在的可读可写数据段
call create_descriptor ; 0xc0:粒度为4k, 段的上部界限为4G
; 0x20:DPL--描述符特权级为1 ; 0x20:DPL--描述符特权级为1
mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
mov dword [esp + 1 * 4], 3 ; 第4个描述符,从0开始
mov dword [esp + 2 * 4], 0xb8000 ;显存段的起始地址
mov dword [esp + 3 * 4], 0xfffff ; 段限长为0xfff * 4k
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60 ; 0x9a:存在的可读可写数据段
call create_descriptor ; 0xc0:粒度为4k, 段的上部界限为4G
; 0x20:DPL--描述符特权级为1
sub ebx, process_control.ldt + 0x100000
mov edx, ebx
mov ebx, 21
add ebx, eax
shl ebx, 3
mov dword [edx + process_control.ldt_sel], ebx
mov dword [edx + process_stack.gs], 3 * 8 + 7
mov dword [edx + process_stack.fs], 2 * 8 + 7
mov dword [edx + process_stack.es], 2 * 8 + 7
mov dword [edx + process_stack.ss], 2 * 8 + 7
mov dword [edx + process_stack.ds], 2 * 8 + 7
mov dword [edx + process_stack.cs], 1 * 8 + 7
mov dword [edx + process_stack.eflags], 0x1202
mov esi, function_point
mov ebx, eax
shl ebx, 2
add esi, ebx
mov ebx, [esi]
mov dword [edx + process_stack.eip], ebx
mov esi, task_or_user_stack_top
mov ebx, eax
shl ebx, 9
sub esi, ebx
mov dword [edx + process_stack.esp], esi
inc eax
dec ecx
cmp ecx, 0
jne .2
add esp, 20 * 4
popa
leave
ret
; void set_page(void)
; call set_page
set_page:
enter
pusha
mov eax, PAGE_TABLE_BASE + 3
mov edi, page_dir_start
mov ecx, 1024
.1:
stosd
add eax, 0x1000
loop .1
mov eax, 0 + 3
mov edi, page_table_start
mov ecx, 8 * 1024
.2:
stosd
add eax, 0x1000
loop .2
mov eax, PAGE_DIR_BASE
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0 ,eax
jmp short .page
.page:
popa
leave
ret
; int _add(int a, int b)
; mov eax, [num1]
; mov [esp + 0 * 4], eax
; mov eax, [num2]
; mov [esp + 1 * 4], eax
; call _add
; mov [result], eax
_add:
enter
push_some
mov eax, [ebp + 2 * 4]
add eax, [ebp + 3 * 4]
pop_some
leave
ret
; void init_8259(void)
; call init_8259
init_8259:
enter
pusha
mov al, 0x11
out 0x20, al
out 0xa0, al
mov al, 0x20
out 0x21, al
mov al, 0x28
out 0xa1, al
mov al, 0x4
out 0x21, al
mov al, 0x2
out 0xa1, al
mov al, 0x1
out 0x21, al
out 0xa1, al
mov al, 0xff
out 0x21, al
out 0xa1, al
popa
leave
ret
; void init_8254(void)
; call init_8254
init_8254:
enter
pusha
mov al, 0x34
out 0x43, al
mov al, 0x9c
out 0x40, al
mov al, 0x2e
out 0x40, al
popa
leave
ret
; void init_rtc(void)
; call init_rtc
init_rtc:
enter
pusha
mov al, 0xb
or al, 0x80
out 0x70, al
mov al, 0x12
out 0x71, al
mov al, 0xc
out 0x70, al
in al, 0x71
popa
leave
ret
; void init_idt(void)
; call init_idt
init_idt:
enter
pusha
sub esp, 20 * 4
; init exception in interrupt descriptor table
xor eax, eax
mov ebx, exception_table
mov ecx, 17
.1:
mov esi, [ebx + eax * 4]
; add esi, 0x100000
mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
mov dword [esp + 1 * 4], eax ; clock interrupt
mov dword [esp + 2 * 4], 1 * 8 ; code segment select
mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
mov dword [esp + 4 * 4], esi ; interrupt process program enter address
call create_gate
inc eax
loop .1
; init interrupt in interrupt descriptor table
mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
mov dword [esp + 1 * 4], 0x20 ; clock interrupt
mov dword [esp + 2 * 4], 1 * 8 ; code segment select
mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
mov dword [esp + 4 * 4], clock_int ;+ 0x100000; interrupt process program enter address
call create_gate
mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
mov dword [esp + 1 * 4], 0x21 ; clock interrupt
mov dword [esp + 2 * 4], 1 * 8 ; code segment select
mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
mov dword [esp + 4 * 4], keyboard_int ;+ 0x100000; interrupt process program enter address
call create_gate
mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
mov dword [esp + 1 * 4], 0x28 ; clock interrupt
mov dword [esp + 2 * 4], 1 * 8 ; code segment select
mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
mov dword [esp + 4 * 4], rtc_int ;+ 0x100000; interrupt process program enter address
call create_gate
; init other in interrupt descriptor table
mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
mov dword [esp + 1 * 4], 0x80 ; clock interrupt
mov dword [esp + 2 * 4], 1 * 8 ; code segment select
mov dword [esp + 3 * 4], 0x8e00 + 0x6000; interrupt gate
mov dword [esp + 4 * 4], system_call ;+ 0x100000; interrupt process program enter address
call create_gate
add esp, 20 * 4
popa
leave
ret
;;;;;system_call;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
system_call:
interrupt_head .1
mov edi, esp
mov esp, stack_top
jmp .2
.1:
sti
call [system_call_table + eax * 4]
mov dword [edi + 11 * 4], eax
cli
jmp .re_start_re_enter
.2:
sti
call [system_call_table + eax * 4]
mov dword [edi + 11 * 4], eax
cli
interrupt_tail .re_start, .re_start_re_enter
align 32
system_call_table: dd system_get_ticks, my_cpuid
align 32
system_get_ticks:
enter
push_some
mov eax, [clock_count]
pop_some
leave
ret
align 32
cpuid_data: dd 0, 0, 0, 0
my_cpuid: ;int my_cpuid(void)
enter
push_some
mov eax, 0
cpuid
mov [cpuid_data + 0 * 4], ebx
mov [cpuid_data + 1 * 4], edx
mov [cpuid_data + 2 * 4], ecx
pop_some
leave
ret
; void cls(void)
; call cls
cls:
enter
pusha
xor ebx, ebx
mov al, ' '
mov ah, 0xf
mov ecx, 2000
.1:
mov [gs: ebx], ax
inc ebx
inc ebx
loop .1
popa
leave
ret
; void print_c(char c, int colour)
; mov dword [esp + 0 * 4], 'a'
; mov dwrod [esp + 1 * 4], 0xf
; call print_c
print_c:
enter
pusha
mov ebx, [cursor_pos]
mov al, [ebp + 2 * 4]
mov ah, [ebp + 3 * 4]
mov [gs: ebx], ax
inc ebx
inc ebx
mov [cursor_pos], ebx
shr ebx, 1
; mov al, 0xe
; mov dx, 0x3d4
; out dx, al
; mov al, bh
; mov dx, 0x3d5
; out dx, al
; mov al, 0xf
; mov dx, 0x3d4
; out dx, al
; mov al, bl
; mov dx, 0x3d5
; out dx, al
popa
leave
ret
; int strlen(char* s)
; mov dword [esp + 0 * 4], str
; call strlen
; return value in EAX
strlen:
enter
push_some
xor eax, eax
mov ecx, 0xffff_ffff
mov edi, [ebp + 2 * 4]
repne
scasb
not ecx
dec ecx
mov eax, ecx
pop_some
leave
ret
; void print_s(char* s, int colour)
; mov dword [esp + 0 * 4], str
; mov dword [esp + 1 * 4], 0xf
; call print_s
print_s:
enter
pusha
mov ebx, [ebp + 2 * 4]
mov dword [esp + 0 * 4], ebx
call strlen
mov ecx, eax
mov ah, [ebp + 3 * 4]
.1:
mov al, [ebx]
inc ebx
mov [esp + 0 * 4], al
mov [esp + 1 * 4], ah
call print_c
loop .1
popa
leave
ret
; void print_s(char* s, int color, int pos)
; mov dword [esp + 0 * 4], rtc_clock_str
; mov dword [esp + 1 * 4], 0xe
; mov dword [esp + 2 * 4], 24 * 80 * 2 + 0
; call print_pos
print_pos:
enter
push_some
sub esp, 30 * 4
mov esi, [ebp + 2 * 4]
mov [esp], esi
call strlen
mov ecx, eax
mov ah, [ebp + 3 * 4]
mov ebx, [ebp + 4 * 4]
.1:
mov al, [esi]
inc esi
mov [gs:ebx], ax
inc ebx
inc ebx
loop .1
add esp, 30 * 4
pop_some
leave
ret
; unsigned char bcd_ascii(unsigned char)
; mov al, [rtc_clock + 0]
; mov [esp + 0 * 4], al
; call bcd_ascii
bcd_ascii:
enter
push_some
mov al, [ebp + 2 * 4]
mov ah, al
and ah, 00001111b
add ah, '0'
shr al, 4
add al, '0'
pop_some
leave
ret
; void print_clock(void)
; call print_clock
print_clock:
enter
pusha
sub esp, 10 * 4
mov al, [rtc_clock + 0]
mov [esp + 0 * 4], al
call bcd_ascii
mov [rtc_clock_str + 0], al
mov [rtc_clock_str + 1], ah
mov al, [rtc_clock + 1]
mov [esp + 0 * 4], al
call bcd_ascii
mov [rtc_clock_str + 3], al
mov [rtc_clock_str + 4], ah
mov al, [rtc_clock + 2]
mov [esp + 0 * 4], al
call bcd_ascii
mov [rtc_clock_str + 6], al
mov [rtc_clock_str + 7], ah
mov dword [esp + 0 * 4], rtc_clock_str
mov dword [esp + 1 * 4], 0xe
mov dword [esp + 2 * 4], 3 * 80 * 2 + 26
call print_pos
add esp, 10 * 4
popa
leave
ret
; int _div(int* i, int n)
; mov [esp + 0 * 4], ebx
; mov [esp + 1 * 4], edx
; call _div
_div:
enter
push_some
xor edx, edx
mov esi, [ebp + 2 * 4]
mov eax, [esi]
mov ebx, [ebp + 3 * 4]
div ebx
mov [esi], eax
mov eax, edx
pop_some
leave
ret
; void itoa(int i, int n)
; mov eax, [num1]
; mov dword [esp + 0 * 4], eax
; mov dword [esp + 1 * 4], 10
; call itoa
; display result
; mov dword [esp + 0 * 4], ascii_buf
; mov dword [esp + 1 * 4], 0xc
; call print_s
itoa:
enter
pusha
sub esp, 20 * 4
mov esi, temp_buf
mov edx, [ebp + 3 * 4]
xor ecx, ecx
.1:
lea ebx, [ebp + 2 * 4]
mov [esp + 0 * 4], ebx
mov [esp + 1 * 4], edx
call _div
mov edi, number
add edi, eax
mov al, [edi]
mov [esi], al
inc esi
inc ecx
cmp dword [ebx], 0
jne .1
mov esi, temp_buf
add esi, ecx
mov edi, ascii_buf
.2:
dec esi
mov al, [esi]
mov [edi], al
inc edi
loop .2
mov byte [edi], 0
add esp, 20 * 4
popa
leave
ret
;;;;;global_value;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
number: db '0123456789abcdef', 0
ascii_buf:
times 32 db 0
temp_buf:
times 32 db 0
cursor_pos: dd 0
num1: dd 20
num2: dd 30
result: dd 0
clock_count: dd 0
rtc_count: dd 0
rtc_clock: dd 0, 0
rtc_clock_str: db '00:00:00', 0
;;;;;message_area;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message_area:
str1: db 'Hello, World!', 0
clock_int_message: db 'Clock Interrupt...', 0
keyboard_int_message: db 'Keyboard Interrupt...', 0
;;;;;exception;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
no_error_code:
mov eax, [esp + 0 * 4] ; exception number
mov ecx, [esp + 1 * 4] ; eip
mov edx, [esp + 2 * 4] ; cs
mov ebx, [esp + 3 * 4] ; eflags
sub esp, 20 * 4
shl eax, 2
add eax, exception_msg_table
mov edi, [eax]
mov dword [esp + 0 * 4], edi
mov dword [esp + 1 * 4], 0xc
call print_s
mov dword [esp + 0 * 4], ecx
mov dword [esp + 1 * 4], 16
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
call print_s
mov dword [esp + 0 * 4], ' '
mov dword [esp + 1 * 4], 0xf
call print_c
mov dword [esp + 0 * 4], edx
mov dword [esp + 1 * 4], 16
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
call print_s
mov dword [esp + 0 * 4], ' '
mov dword [esp + 1 * 4], 0xf
call print_c
mov dword [esp + 0 * 4], ebx
mov dword [esp + 1 * 4], 16
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
call print_s
mov dword [esp + 0 * 4], ' '
mov dword [esp + 1 * 4], 0xf
call print_c
add esp, 20 * 4
.1:
hlt
jmp .1
error_code:
mov eax, [esp + 0 * 4] ; exception number
mov ecx, [esp + 1 * 4] ; error_code
mov edx, [esp + 2 * 4] ; eip
mov ebx, [esp + 3 * 4] ; cs
mov esi, [esp + 4 * 4] ; eflags
sub esp, 20 * 4
shl eax, 2
add eax, exception_msg_table
mov edi, [eax]
mov dword [esp + 0 * 4], edi
mov dword [esp + 1 * 4], 0xc
call print_s
mov dword [esp + 0 * 4], ecx
mov dword [esp + 1 * 4], 16
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
call print_s
mov dword [esp + 0 * 4], ' '
mov dword [esp + 1 * 4], 0xf
call print_c
mov dword [esp + 0 * 4], edx
mov dword [esp + 1 * 4], 16
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
call print_s
mov dword [esp + 0 * 4], ' '
mov dword [esp + 1 * 4], 0xf
call print_c
mov dword [esp + 0 * 4], ebx
mov dword [esp + 1 * 4], 16
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
call print_s
mov dword [esp + 0 * 4], ' '
mov dword [esp + 1 * 4], 0xf
call print_c
mov dword [esp + 0 * 4], esi
mov dword [esp + 1 * 4], 16
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
call print_s
mov dword [esp + 0 * 4], ' '
mov dword [esp + 1 * 4], 0xf
call print_c
add esp, 20 * 4
.1:
hlt
jmp .1
divide_error:
push 0
jmp no_error_code
debug:
push 1
jmp no_error_code
nmi:
push 2
jmp no_error_code
break_point:
push 3
jmp no_error_code
overflow:
push 4
jmp no_error_code
bound_check:
push 5
jmp no_error_code
invalid_instruction:
push 6
jmp no_error_code
device_not_available:
push 7
jmp no_error_code
double_fault:
push 8
jmp error_code
coprocessor_segment_overrun:
push 9
jmp no_error_code
invalid_tss:
push 10
jmp error_code
segment_not_present:
push 11
jmp error_code
stack_fault:
push 12
jmp error_code
general_protection:
push 13
jmp error_code
page_fault:
push 14
jmp error_code
reserved:
push 15
.1:
hlt
jmp .1
coprocessor_error:
push 16
jmp no_error_code
align 32
exception_table:
dd divide_error, debug, nmi, break_point, \
overflow, bound_check, invalid_instruction, device_not_available, \
double_fault, coprocessor_segment_overrun, invalid_tss, \
segment_not_present, stack_fault, general_protection, \
page_fault, reserved, coprocessor_error
divide_error_msg: db "divide_error...#0: ", 0
debug_msg: db "debug...#1: ", 0
nmi_msg: db "nmi...#2: ", 0
break_point_msg: db "break_point...#3: ", 0
overflow_msg: db "overflow...#4: ", 0
bound_check_msg: db "bound_check...#5: ", 0
invalid_instruction_msg: db "invalid_instruction...#6: ", 0
device_not_available_msg: db "device_not_available...#7: ", 0
double_fault_msg: db "double_fault...#8: ", 0
coprocessor_segment_overrun_msg: db "coprocessor_segment_overrun...#9: ", 0
invalid_tss_msg: db "invalid_tss...#10: ", 0
segment_not_present_msg: db "segment_not_present...#11: ", 0
stack_fault_msg: db "stack_fault...#12: ", 0
general_protection_msg: db "general_protection...#13: ", 0
page_fault_msg: db "page_fault...#14: ", 0
reserved_msg: db "reserved...#15: ", 0
coprocessor_error_msg: db "coprocessor_error...#16: ", 0
exception_msg_table:
dd divide_error_msg, debug_msg, nmi_msg, break_point_msg, \
overflow_msg, bound_check_msg, invalid_instruction_msg, device_not_available_msg, \
double_fault_msg, coprocessor_segment_overrun_msg, invalid_tss_msg, \
segment_not_present_msg, stack_fault_msg, general_protection_msg, \
page_fault_msg, reserved_msg, coprocessor_error_msg
;;;;;interrupt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
re_start:
mov esp, [process_table_point]
lldt [esp + process_control.ldt_sel]
lea eax, [esp + 18 * 4]
mov [tss_start + tss.esp0], eax
re_start_re_enter:
dec dword [re_enter_flags]
pop gs
pop fs
pop es
pop ds
popa
add esp, 4
iret
align 32
clock_int:
interrupt_head .1
mov esp, stack_top
jmp .2
.1:
in al, 0x21
or al, 0x01
out 0x21, al
mov al, 0x20
out 0x20, al
sti
call clock_handler
cli
in al, 0x21
and al, 0xfe
out 0x21, al
jmp .re_start_re_enter
.2:
in al, 0x21
or al, 0x01
out 0x21, al
mov al, 0x20
out 0x20, al
sti
call sche
cli
in al, 0x21
and al, 0xfe
out 0x21, al
interrupt_tail .re_start, .re_start_re_enter
delay: ; void delay(int times)
enter
pusha
mov ecx, [ebp + 2 * 4]
.1:
nop
nop
loop .1
popa
leave
ret
re_enter_flags: dd 0
clock_handler:
enter
pusha
inc dword [clock_count]
call sche
push dword 10
push dword [clock_count]
call itoa
add esp, 2 * 4
push dword 24 * 160 + 0
push dword 0xc
push dword ascii_buf
call print_pos
add esp, 3 * 4
popa
leave
ret
sche:
enter
pusha
add dword [process_table_point], 36 * 4
cmp dword [process_table_point], process_table_start + 5 * 36 * 4
jbe .1
mov dword [process_table_point], process_table_start
.1:
popa
leave
ret
align 32
keyboard_int:
interrupt_head .1
mov esp, stack_top
jmp .2
.1:
in al, 0x21
or al, 0000_0100b
out 0x21, al
mov al, 0x20
out 0x20, al
sti
call keyboard_handler
cli
in al, 0x21
and al, 1111_1011b
out 0x21, al
jmp .re_start_re_enter
.2:
in al, 0x21
or al, 0000_0100b
out 0x21, al
mov al, 0x20
out 0x20, al
sti
call keyboard_handler
cli
in al, 0x21
and al, 1111_1011b
out 0x21, al
interrupt_tail .re_start, .re_start_re_enter
make: dd 0
keyboard_handler:
enter
pusha
xor eax, eax
in al, 0x60
cmp al, 0xe1
je .end
cmp al, 0xe0
je .end
mov ah, al
and ah, 0x80
cmp ah, 0
jnz .end
mov dword [make], 1
and eax, 0x7f
mov ebx, eax
shl eax, 1
add ebx, eax
xor eax, eax
mov al, [key_map + ebx]
push dword 0xf
push dword eax
call print_c
add esp, 2 * 4
.end:
popa
leave
ret
align 32
rtc_int:
interrupt_head .1
mov esp, stack_top
jmp .2
.1:
in al, 0xa1
or al, 0000_0001b
out 0xa1, al
mov al, 0x20
out 0x20, al
out 0xa0, al
sti
call rtc_handler
cli
in al, 0xa1
and al, 1111_1110b
out 0xa1, al
jmp .re_start_re_enter
.2:
in al, 0xa1
or al, 0000_0001b
out 0xa1, al
mov al, 0x20
out 0x20, al
out 0xa0, al
sti
call rtc_handler
cli
in al, 0xa1
and al, 1111_1110b
out 0xa1, al
interrupt_tail .re_start, .re_start_re_enter
rtc_handler:
enter
pusha
.1:
; mov al, 0x8a
; out 0x70, al
; in al, 0x71
; test al, 0x80
; jnz .1
mov al, 4
out 0x70, al
in al, 0x71
mov [rtc_clock + 0], al
mov al, 2
out 0x70, al
in al, 0x71
mov [rtc_clock + 1], al
mov al, 0
out 0x70, al
in al, 0x71
mov [rtc_clock + 2], al
mov al, 0xc
out 0x70, al
in al, 0x71
inc dword [rtc_count]
popa
leave
ret
;;;;;other_function;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
msg1: db 'TASK1:', 0
msg2: db 'TASK2:', 0
msg3: db 'TASK3:', 0
msg4: db 'U_TASK4:', 0
msg5: db 'U_TASK5:', 0
msg6: db 'U_TASK6:', 0
align 4 * 1024
; void function1(void)
function1_start:
enter
pusha
sub esp, 20 * 4
mov dword [esp + 0 * 4], msg1
mov dword [esp + 1 * 4], 0xc
mov dword [esp + 2 * 4], 0 * 160 + 0
call print_pos
.1:
mov eax, [clock_count]
mov dword [esp + 0 * 4], eax
mov dword [esp + 1 * 4], 10
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0xa
mov dword [esp + 2 * 4], 0 * 160 + 20
call print_pos
jmp .1
add esp, 20 * 4
popa
leave
ret
function1_end:
align 32
function2_start:
enter
pusha
sub esp, 20 * 4
mov dword [esp + 0 * 4], msg2
mov dword [esp + 1 * 4], 0xc
mov dword [esp + 2 * 4], 1 * 160 + 0
call print_pos
mov byte [gs: 160 + 20], '0'
mov byte [gs: 161 + 20], 0xb
.1:
cmp byte [gs: 160 + 20], '9'
ja .2
inc byte [gs: 160 + 20]
mov byte [gs: 161 + 20], 0xb
jmp .1
.2:
mov byte [gs: 160 + 20], '0'
jmp .1
add esp, 20 * 4
popa
leave
ret
function2_end:
align 32
function3_start:
enter
pusha
sub esp, 20 * 4
mov dword [esp + 0 * 4], msg3
mov dword [esp + 1 * 4], 0xc
mov dword [esp + 2 * 4], 2 * 160 + 0
call print_pos
mov byte [gs: 320 + 20], 'A'
mov byte [gs: 321 + 20], 0xc
.1:
cmp byte [gs: 320 + 20], 'Z'
ja .2
inc byte [gs: 320 + 20]
mov byte [gs: 321 + 20], 0xc
jmp .1
.2:
mov byte [gs: 320 + 20], 'A'
jmp .1
add esp, 20 * 4
popa
leave
ret
function3_end:
align 32
function4_start:
enter
pusha
sub esp, 20 * 4
mov dword [esp + 0 * 4], msg4
mov dword [esp + 1 * 4], 0xf
mov dword [esp + 2 * 4], 3 * 160 + 0
call print_pos
mov eax, 1
int 0x80
mov dword [esp + 0 * 4], cpuid_data
mov dword [esp + 1 * 4], 0xc
mov dword [esp + 2 * 4], 3 * 160 + 80
call print_pos
.1:
call print_clock
jmp .1
add esp, 20 * 4
popa
leave
ret
function4_end:
align 32
function5_start:
enter
pusha
sub esp, 20 * 4
mov dword [esp + 0 * 4], msg5
mov dword [esp + 1 * 4], 0xf
mov dword [esp + 2 * 4], 4 * 160 + 0
call print_pos
.1:
mov eax, 0
int 0x80
mov dword [esp + 0 * 4], eax
mov dword [esp + 1 * 4], 10
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0xd
mov dword [esp + 2 * 4], 4 * 2 * 80 + 20
call print_pos
jmp .1
add esp, 20 * 4
popa
leave
ret
function5_end:
align 32
function6_start:
enter
pusha
sub esp, 20 * 4
mov dword [esp + 0 * 4], msg6
mov dword [esp + 1 * 4], 0xf
mov dword [esp + 2 * 4], 5 * 160 + 0
call print_pos
mov dword [esp + 0 * 4], '6'
mov dword [esp + 1 * 4], 0xb
call print_c
.1:
; mov dword [esp + 0 * 4], 'M'
; mov dword [esp + 1 * 4], 0x9
; call print_c
call my_delay
; mov eax, 0
; int 0x80
mov eax, [rtc_count]
mov dword [esp + 0 * 4], eax
mov dword [esp + 1 * 4], 10
call itoa
mov dword [esp + 0 * 4], ascii_buf
mov dword [esp + 1 * 4], 0x9
mov dword [esp + 2 * 4], 5 * 2 * 80 + 40
call print_pos
jmp .1
add esp, 20 * 4
popa
leave
ret
function6_end:
function_point dd function1_start, function2_start, function3_start, function4_start, function5_start,\
function6_start
align 1024
task_or_user_stack_bottom:
times 64 * 128 dd 0
task_or_user_stack_top:
align 4096
code_segment_test:
nop
retf
;;;;;about process;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
process_table_start:
times 64 * 36 dd 0
process_table_end:
process_table_point: dd process_table_start
align 32
tss_start:
times 1 * 26 dd 0
tss_end:
align 32
get_ticks: ; int get_ticks(void) ;int system_get_ticks(void)
;给系统调用get_ticks包装一下 这个东西对于纯汇编语言的系统似乎的多余的
enter
push_some
mov eax, 0
int 0x80
pop_some
leave
ret
align 32
my_delay:
enter
push_some
sub esp, 1 * 4
call get_ticks
mov [esp], eax
add dword [esp], 100
.1:
call get_ticks
cmp eax, [esp]
jbe .1
mov eax, 1
add esp, 1 * 4
pop_some
leave
ret
align 32
key_map:
; 0
db 0, 0, 0 ; 0x00 none
db 0, 0, 0 ; 0x01 esc
db '1', '!', 0 ; 0x02 '1'
db '2', '@', 0 ; 0x03 '2'
db '3', '#', 0 ; 0x04 '3'
db '4', '$', 0 ; 0x05 '4'
db '5', '%', 0 ; 0x06 '5'
db '6', '^', 0 ; 0x07 '6'
db '7', '&', 0 ; 0x08 '7'
db '8', '*', 0 ; 0x09 '8'
db '9', '(', 0 ; 0x0a '9'
db '0', ')', 0 ; 0x0b '0'
db '-', '_', 0 ; 0x0c '-'
db '=', '+', 0 ; 0x0d '='
db 8, 8, 8 ; 0x0e backspace
db 0, 0, 0 ; 0x0f tab
; 1
db 'q', 'Q', 0 ; 0x10 'q'
db 'w', 'W', 0 ; 0x11 'w'
db 'e', 'E', 0 ; 0x12 'e'
db 'r', 'R', 0 ; 0x13 'r'
db 't', 'T', 0 ; 0x14 't'
db 'y', 'Y', 0 ; 0x15 'y'
db 'u', 'U', 0 ; 0x16 'u'
db 'i', 'I', 0 ; 0x17 'i'
db 'o', 'O', 0 ; 0x18 'o'
db 'p', 'P', 0 ; 0x19 'p'
db '[', '{', 0 ; 0x1a 'i'
db ']', '}', 0 ; 0x1b 'o'
db 0xa, 0, 0 ; 0x1c enter
db '[', '{', 0 ; 0x1d ctrl
db 'a', 'A', 0 ; 0x1e 'a'
db 's', 'S', 0 ; 0x1f 's'
; 2
db 'd', 'D', 0 ; 0x20 'd'
db 'f', 'F', 0 ; 0x21 'f'
db 'g', 'G', 0 ; 0x22 'g'
db 'h', 'H', 0 ; 0x23 'h'
db 'j', 'J', 0 ; 0x24 'j'
db 'k', 'K', 0 ; 0x25 'k'
db 'l', 'L', 0 ; 0x26 'l'
db ';', ':', 0 ; 0x27 ';'
db "'", '"', 0 ; 0x28 '\'
db '`', '~', 0 ; 0x29 '`'
db 0, 0, 0 ; 0x2a shift left
db '\', '|', 0 ; 0x2b 'o'
db 'z', 'Z', 0 ; 0x2c 'z'
db 'x', 'X', 0 ; 0x2d 'x'
db 'c', 'C', 0 ; 0x2e 'c'
db 'v', 'V', 0 ; 0x2f 'v'
; 3
db 'b', 'B', 0 ; 0x30 'b'
db 'n', 'N', 0 ; 0x31 'n'
db 'm', 'M', 0 ; 0x32 'm'
db ',', '<', 0 ; 0x33 ','
db '.', '>', 0 ; 0x34 '.'
db '/', '?', 0 ; 0x35 '/'
db 0, 0, 0 ; 0x36
db 0, 0, 0 ; 0x37
db 0, 0, 0 ; 0x38
db ' ', ' ', 0 ; 0x39
db 0, 0, 0 ; 0x3a
db 0, 0, 0 ; 0x3b
db 0, 0, 0 ; 0x3c
db 0, 0, 0 ; 0x3d
db 0, 0, 0 ; 0x3e
db 0, 0, 0 ; 0x3f
; 4
db 0, 0, 0 ; 0x40
db 0, 0, 0 ; 0x41
db 0, 0, 0 ; 0x42
db 0, 0, 0 ; 0x43
db 0, 0, 0 ; 0x44
db 0, 0, 0 ; 0x45
db 0, 0, 0 ; 0x46
db 0, 0, 0 ; 0x47
db 0, 0, 0 ; 0x48
db 0, 0, 0 ; 0x49
db 0, 0, 0 ; 0x4a
db 0, 0, 0 ; 0x4b
db 0, 0, 0 ; 0x4c
db 0, 0, 0 ; 0x4d
db 0, 0, 0 ; 0x4e
db 0, 0, 0 ; 0x4f
; 5
db 0, 0, 0 ; 0x_0
db 0, 0, 0 ; 0x_1
db 0, 0, 0 ; 0x_2
db 0, 0, 0 ; 0x_3
db 0, 0, 0 ; 0x_4
db 0, 0, 0 ; 0x_5
db 0, 0, 0 ; 0x_6
db 0, 0, 0 ; 0x_7
db 0, 0, 0 ; 0x_8
db 0, 0, 0 ; 0x_9
db 0, 0, 0 ; 0x_a
db 0, 0, 0 ; 0x_b
db 0, 0, 0 ; 0x_c
db 0, 0, 0 ; 0x_d
db 0, 0, 0 ; 0x_e
db 0, 0, 0 ; 0x_f
; 6
db 0, 0, 0 ; 0x_0
db 0, 0, 0 ; 0x_1
db 0, 0, 0 ; 0x_2
db 0, 0, 0 ; 0x_3
db 0, 0, 0 ; 0x_4
db 0, 0, 0 ; 0x_5
db 0, 0, 0 ; 0x_6
db 0, 0, 0 ; 0x_7
db 0, 0, 0 ; 0x_8
db 0, 0, 0 ; 0x_9
db 0, 0, 0 ; 0x_a
db 0, 0, 0 ; 0x_b
db 0, 0, 0 ; 0x_c
db 0, 0, 0 ; 0x_d
db 0, 0, 0 ; 0x_e
db 0, 0, 0 ; 0x_f
; 7
db 0, 0, 0 ; 0x_0
db 0, 0, 0 ; 0x_1
db 0, 0, 0 ; 0x_2
db 0, 0, 0 ; 0x_3
db 0, 0, 0 ; 0x_4
db 0, 0, 0 ; 0x_5
db 0, 0, 0 ; 0x_6
db 0, 0, 0 ; 0x_7
db 0, 0, 0 ; 0x_8
db 0, 0, 0 ; 0x_9
db 0, 0, 0 ; 0x_a
db 0, 0, 0 ; 0x_b
db 0, 0, 0 ; 0x_c
db 0, 0, 0 ; 0x_d
db 0, 0, 0 ; 0x_e
db 0, 0, 0 ; 0x_f
; syslib.asm
%include "sysmacro.asm"
u8 equ 1
u16 equ 2
u32 equ 4
u64 equ 8
struc tss ; 26 double word
.backlink resb u32
.esp0 resb u32
.ss0 resb u32
.esp1 resb u32
.ss1 resb u32
.esp2 resb u32
.ss2 resb u32
.cr3 resb u32
.eip resb u32
.flags resb u32
.eax resb u32
.ecx resb u32
.edx resb u32
.ebx resb u32
.esp resb u32
.ebp resb u32
.esi resb u32
.edi resb u32
.es resb u32
.cs resb u32
.ss resb u32
.ds resb u32
.fs resb u32
.gs resb u32
.ldt resb u32
.trap resb u16
.iobase resb u16
endstruc
struc process_stack
.gs: resb u32 ; #0
.fs: resb u32
.es: resb u32
.ds: resb u32
.edi: resb u32
.esi: resb u32
.ebp: resb u32
.kernel_esp: resb u32
.ebx: resb u32
.edx: resb u32
.ecx: resb u32
.eax: resb u32
.retaddr: resb u32
.eip: resb u32
.cs: resb u32
.eflags: resb u32
.esp: resb u32
.ss: resb u32 ; #17
endstruc
ldt_size equ 4
struc process_control ; 18 + 1 + 8 + 1 + 8 double word = 36
.process_stack resb 18 * u32 ; 18 double word
.ldt_sel resb u32 ; 1 double word
.ldt resb ldt_size * u64 ; 8 double word
.pid resb u32 ; 1 double word
.process_name resb 32 * u8 ; 8 double word
endstruc
; void create_descriptor(int table_start, int number, int base, int limit, int attrib)
; mov dword [esp + 0 * 4], 0x7c00
; mov dword [esp + 1 * 4], 1
; mov dword [esp + 2 * 4], 0x100000
; mov dword [esp + 3 * 4], 0x000fffff
; mov dword [esp + 4 * 4], 0x9a + 0xc000
; call create_descriptor
create_descriptor:
enter
pusha
push ds
mov ax, 5 * 8
mov ds, ax
mov word [ebx + 5], 0
mov ebx, [ebp + 2 * 4]
mov ecx, [ebp + 3 * 4]
shl ecx, 3
add ebx, ecx
mov eax, [ebp + 5 * 4]
mov [ebx], ax
shr eax, 16
and al, 0x0f
mov [ebx + 6], al
mov eax, [ebp + 4 * 4]
mov ecx, eax
and eax, 0x00ffffff
mov [ebx + 2], eax
shr ecx, 24
mov [ebx + 7], cl
mov ax, [ebp + 6 * 4]
or [ebx + 5], ax
pop ds
popa
leave
ret
; void create_gate(int table_start, int irq, int select, int attrib, int offset)
; mov dword [esp + 0 * 4], 0x7c00 + 256 * 8 ; interrupt descriptor table start
; mov dword [esp + 1 * 4], 0x20 ; clock interrupt
; mov dword [esp + 2 * 4], 4 * 8 ; code segment select
; mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
; mov dword [esp + 4 * 4], clock_int ; interrupt process program enter address
; call create_gate
create_gate:
enter
pusha
push ds
mov ax, 5 * 8
mov ds, ax
mov ebx, [ebp + 2 * 4]
mov ecx, [ebp + 3 * 4]
shl ecx, 3
add ebx, ecx
mov ax, [ebp + 4 * 4]
mov [ebx + 2], ax
mov ax, [ebp + 5 * 4]
mov [ebx + 4], ax
mov eax, [ebp + 6 * 4]
mov [ebx + 0], ax
shr eax, 16
mov [ebx + 6], ax
pop ds
popa
leave
ret
; void load_hd_to_mem(int sector_start, int sectors, int mem_start)
; mov dword [esp + 0 * 4], 21 ; from
; mov dword [esp + 1 * 4], 8196 ; size
; mov dword [esp + 2 * 4], 0x100000 ; memory start
; call load_hd_to_mem
load_hd_to_mem:
enter
pusha
push ds
mov ax, 5 * 8
mov ds, ax
mov esi, [ebp + 2 * 4]
mov ecx, [ebp + 3 * 4]
mov ebx, [ebp + 4 * 4]
.readloop:
mov al, 1
mov dx, 0x1f2
out dx, al
mov eax, esi
mov dx, 0x1f3
out dx, al
shr eax, 8
mov dx, 0x1f4
out dx, al
shr eax, 8
mov dx, 0x1f5
out dx, al
shr eax, 8
and al, 0x0f
or al, 0xe0
mov dx, 0x1f6
out dx, al
mov dx, 0x1f7
mov al, 0x20
out dx, al
mov dx, 0x1f7
.1:
in al, dx
and al, 0x88
cmp al, 0x08
jnz .1
push ecx
mov ecx, 256
mov dx, 0x1f0
.2:
in ax, dx
mov [ebx], ax
inc ebx
inc ebx
loop .2
pop ecx
inc esi
loop .readloop
pop ds
popa
leave
ret
; sysmacro.asm
%macro enter 0
push ebp
mov ebp, esp
%endmacro
%macro push_some 0
push ecx
push edx
push ebx
push esi
push edi
%endmacro
%macro pop_some 0
pop edi
pop esi
pop ebx
pop edx
pop ecx
%endmacro
%macro interrupt_head 1 ; bad select
sub esp, 4
pusha
push ds
push es
push fs
push gs
mov dx, ss
mov ds, dx
mov es, dx
inc dword [re_enter_flags]
cmp dword [re_enter_flags], 0
jne %1
%endmacro
%macro interrupt_tail 2 ; bad select
%1:
mov esp, [process_table_point]
lldt [esp + process_control.ldt_sel]
lea eax, [esp + 18 * 4]
mov [tss_start + tss.esp0], eax
%2:
dec dword [re_enter_flags]
pop gs
pop fs
pop es
pop ds
popa
add esp, 4
iret
%endmacro