CoolPotOS/boot/io.asm

142 lines
2.6 KiB
NASM
Raw Normal View History

2024-04-09 23:46:56 +08:00
section .data
global io_hlt, io_cli, io_sti, io_stihlt
global io_in8, io_in16, io_in32
global io_out8, io_out16, io_out32
global io_load_eflags, io_store_eflags
global load_gdtr, load_idtr
global tss_flush, gdt_flush, switch_to
section .text
switch_to:
mov eax, [esp+4]
mov [eax+0], esp
mov [eax+4], ebp
mov [eax+8], ebx
mov [eax+12], esi
mov [eax+16], edi
pushf
pop ecx
mov [eax+20], ecx
mov eax, [esp+8]
mov esp, [eax+0]
mov ebp, [eax+4]
mov ebx, [eax+8]
mov esi, [eax+12]
mov edi, [eax+16]
mov eax, [eax+20]
push eax
popf
ret
[global read_port]
read_port:
mov edx, [esp + 4]
in al, dx
ret
[global idt_flush]
idt_flush: ; void idt_flush(uint32_t);
mov eax, [esp + 4]
lidt [eax]
ret
[global gdt_flush]
gdt_flush: ; void gdt_flush(uint32_t gdtr);
mov eax, [esp + 4] ; [esp+4]按规定是第一个参数即gdtr
lgdt [eax] ; 加载新gdt指针传入的是地址
mov ax, 0x10 ; 新数据段
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax ; 各数据段全部划给这一数据段
jmp 0x08:.flush ; cs没法mov只能用farjmp/farcall这里用farjmp刷新cs
.flush:
ret ; 刷新完毕,返回
tss_flush:
mov ax, 0x2B
ltr ax
ret
io_hlt: ; void io_hlt(void);
HLT
RET
io_cli: ; void io_cli(void);
CLI
RET
io_sti: ; void io_sti(void);
STI
RET
io_stihlt: ; void io_stihlt(void);
STI
HLT
RET
io_in8: ; int io_in8(int port);
MOV EDX,[ESP+4] ; port
MOV EAX,0
IN AL,DX
RET
io_in16: ; int io_in16(int port);
MOV EDX,[ESP+4] ; port
MOV EAX,0
IN AX,DX
RET
io_in32: ; int io_in32(int port);
MOV EDX,[ESP+4] ; port
IN EAX,DX
RET
io_out8: ; void io_out8(int port, int data);
MOV EDX,[ESP+4] ; port
MOV AL,[ESP+8] ; data
OUT DX,AL
RET
io_out16: ; void io_out16(int port, int data);
MOV EDX,[ESP+4] ; port
MOV EAX,[ESP+8] ; data
OUT DX,AX
RET
io_out32: ; void io_out32(int port, int data);
MOV EDX,[ESP+4] ; port
MOV EAX,[ESP+8] ; data
OUT DX,EAX
RET
io_load_eflags: ; int io_load_eflags(void);
PUSHFD ; PUSH EFLAGS
POP EAX
RET
io_store_eflags: ; void io_store_eflags(int eflags);
MOV EAX,[ESP+4]
PUSH EAX
POPFD ; POP EFLAGS
RET
load_gdtr: ; void load_gdtr(int limit, int addr);
MOV AX,[ESP+4] ; limit
MOV [ESP+6],AX
LGDT [ESP+6]
RET
load_idtr: ; void load_idtr(int limit, int addr);
MOV AX,[ESP+4] ; limit
MOV [ESP+6],AX
LIDT [ESP+6]
RET