%include "pm.inc"org 0x8000jmp LABEL_BEGIN[SECTION .GDT];全局描述符表; 段基址 段界限 属性LABEL_GDT: Descriptor 0, 0, 0LABEL_DESC_CODE_32: Descriptor 0, 0FFFFFh, DA_CR | DA_32 | DA_LIMIT_4K ;结构体初始化时只能传入常量LABEL_DESC_SHOW: Descriptor 0B8000h, 0FFFFFh, DA_DRW ;0B8000h是显存地址,设置该数据段属性为可读写LABEL_DESC_VRAM: Descriptor 0, 0FFFFFh, DA_DRWA | DA_LIMIT_4K ;4G显存,为了C语言开发方便,全部设置为可读写LABEL_DESC_STACK: Descriptor 0, 0FFFFFh, DA_DRWA | DA_32LABEL_DESC_FONT: Descriptor 0, 0FFFFFh, DA_DRW | DA_LIMIT_4K;LABEL_DESC_6: Descriptor 0, 0fffffh, 0409AhLABEL_DESC_7: Descriptor 0, 0, 0LABEL_DESC_8: Descriptor 0, 0, 0LABEL_DESC_9: Descriptor 0, 0, 0LABEL_DESC_10: Descriptor 0, 0, 0%rep 5Descriptor 0, 0, 0%endrepGDTLen EQU $ - LABEL_GDTGDTPtr DW GDTLen - 1DD 0;选择子SelectorCode32 EQU LABEL_DESC_CODE_32 - LABEL_GDTSelectorShow EQU LABEL_DESC_SHOW - LABEL_GDTSelectorStack EQU LABEL_DESC_STACK - LABEL_GDTSelectorVram EQU LABEL_DESC_VRAM - LABEL_GDTSelectorFont EQU LABEL_DESC_FONT - LABEL_GDT;中断描述符表LABEL_IDT:%rep 32Gate SelectorCode32, SpuriousHandler, 0, DA_386IGate%endrep.020h: ;对应主8259A芯片IRQ0引脚,控制时钟中断Gate SelectorCode32, timerHandler, 0, DA_386IGate.021h: ;对应主8259A芯片IRQ1引脚,控制键盘中断Gate SelectorCode32, KeyBoardHandler, 0, DA_386IGate%rep 10Gate SelectorCode32, SpuriousHandler, 0, DA_386IGate%endrep.2ch: ;对应从8259A芯片IRQ4引脚,控制鼠标中断Gate SelectorCode32, MouseHandler, 0, DA_386IGateIdtLen EQU $ - LABEL_IDTIdtPtr DW IdtLen - 1DD 0[SECTION .s16][BITS 16]LABEL_BEGIN:mov ax, cs ;初始化mov ds, axmov es, axmov ss, axmov sp, 0100h;====== 检测内存 ========ComputeMem:mov ebx, 0mov di, MemCheckBuf.loop:mov eax, 0E820h ;固定值mov ecx, 20 ;es:di内存大小为20字节mov edx, 0534D4150h ;表示" SMAP"int 15hjc LABEL_MEM_CHECK_FAIL ;CF=1表示失败add di, 20inc dword [dwMCRNumber]cmp ebx, 0 ;ebx在内存检测过程中不能被修改,当ebx为0时表示检测完成jne .loopjmp LABEL_MEM_CHECK_OKLABEL_MEM_CHECK_FAIL:mov dword [dwMCRNumber], 0;========================LABEL_MEM_CHECK_OK:;对于超级VGA显示卡,我们可用AX=4F02H和下列BX 的值来设置其显示模式×ばつ480 256色;4103H: ×ばつ600 256色;4105H: 1024*768;4107H: 1280*1024;设置显示器模式mov bx, 0x4101 ;分辨率更改为640*480mov ax, 0x4f02;mov al, 0x13 ;al×ばつ480 256色;mov ah, 0 ;ah寄存器的值表示设置显示器模式int 0x10 ;调用系统中断的显示服务;起始地址写入byte2,3,4,7xor eax, eax ;清零mov ax, csshl eax, 4add eax, LABEL_SEG_CODE32mov word [LABEL_DESC_CODE_32 + 2], axshr eax, 16mov byte [LABEL_DESC_CODE_32 + 4], almov byte [LABEL_DESC_CODE_32 + 7], ah;设置C语言堆栈区;xor eax, eax;mov ax, ds;shl eax, 4;add eax, LABEL_STACK;mov word [LABEL_DESC_STACK + 2], ax;shr eax, 16;mov byte [LABEL_DESC_STACK + 4], al;mov byte [LABEL_DESC_STACK + 7], ahxor eax, eaxmov ax, csshl eax, 4add eax, LABEL_SYSTEM_FONTmov word [LABEL_DESC_FONT + 2], axshr eax, 16mov byte [LABEL_DESC_FONT + 4], almov byte [LABEL_DESC_FONT + 7], ahxor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_GDTmov dword [GDTPtr + 2], eaxlgdt [GDTPtr]cli ;关中断call init8259A ;初始化8259A控制器;准备加载IDTxor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_IDTmov dword [IdtPtr + 2], eaxlidt [IdtPtr]in al, 92h ;打开A20地址线or al, 00000010bout 92h, almov eax, cr0or eax, 1mov cr0, eax ;设置cr0的PE位为1,进入保护模式;jmp dword SelectorCode32:0clijmp dword 1 * 8 : 0init8259A:mov al, 011h ;向主8259A 20h端口发送ICW1,00010001b,表示需要发送ICW4,级联,8字节中断向量,边沿触发out 020h, alcall io_delayout 0A0h, al ;向从8259A a0h端口发送ICW1,00010001b,含义同上call io_delaymov al, 020h ;向主8259A 21h端口发送ICW2,00100000b,表示IR0中断向量为20hout 021h, alcall io_delaymov al, 028h ;向从8259A a1h端口发送ICW2,00101000b,表示IR0中断向量为28hout 0A1h, alcall io_delaymov al, 04h ;向主8259A 21h端口发送ICW3,00000100b,表示主8259A通过IR2引脚连接到从8259Aout 021h, alcall io_delaymov al, 02h ;向从8259A a1h端口发送ICW3,00000010b,表示从8259A是连接到主8259A的IR2引脚out 0A1h, alcall io_delaymov al, 01h ;向主8259A 21h端口发送ICW4,00000001b,表示当前架构为80x86,非自动EOI(ICW4[1]=0)out 021h, alcall io_delayout 0A1h, al ;同上call io_delaymov al, 11111000b ;向主8259A发送OCW1,只能写入奇地址端口,允许键盘和时钟中断,打开主8259A控制器的IRQ1和IRQ2号引脚out 21h, alcall io_delaymov al, 11101111b ;向从8259A发送OCW1,只能写入奇地址端口,允许鼠标中断,打开从8259A控制器的IRQ4号引脚out 0A1h, alcall io_delayretio_delay:nopnopnopnopret[SECTION .s32][BITS 32];初始化C语言栈LABEL_SEG_CODE32:mov ax, SelectorStackmov ss, axmov esp, 4096 ;changemov ax, SelectorVrammov ds, axmov ax, SelectorShowmov gs, axcli%include "ckernel.asm"jmp $;=============================== 中断处理函数 ======================================_SpuriousHandler:SpuriousHandler equ _SpuriousHandler - $$iretd;键盘中断处理函数_KeyBoardHandler:KeyBoardHandler equ _KeyBoardHandler - $$push es ;保护现场push dspushad ;将eax,ebx等所有的32位通用寄存器压入堆栈mov eax, esppush eaxcall intHandlerFromCpop eaxmov esp, eaxpopadpop dspop esiretd;键盘中断处理函数_MouseHandler:MouseHandler equ _MouseHandler - $$push es ;保护现场push dspushad ;将eax,ebx等所有的32位通用寄存器压入堆栈mov eax, esppush eaxcall intHandlerForMousepop eaxmov esp, eaxpopadpop dspop esiretd;时钟中断处理函数_timerHandler:timerHandler equ _timerHandler - $$pushadpush espush dspush fspush gscall intHandlerForTimerpop gspop fspop dspop espopadiretd;===================================================================================get_font_data:mov ax, SelectorFontmov es, axxor edi, edimov edi, [esp + 4] ;charshl edi, 4add edi, [esp + 8]xor eax, eaxmov al, byte [es:edi]retio_hlt: ;void io_hlt(void);HLTRET;关中断,实际上是将标志寄存器第9位的值置0io_cli:CLIRETio_sti:STIRETio_stihlt:STIHLTRET;从指定的端口dx读入一个8位的数值存入alio_in8:mov edx, [esp + 4]mov eax, 0in al, dxret;从指定的端口dx读入一个16位的数值存入axio_in16:mov edx, [esp + 4]mov eax, 0in ax, dxret;从指定的端口dx读入一个32位的数值存入eaxio_in32:mov edx, [esp + 4]in eax, dxret;将al的值写入dx表示的端口中io_out8:mov edx, [esp + 4]mov al, [esp + 8]out dx, alret;写端口16位数io_out16:mov edx, [esp + 4]mov eax, [esp + 8]out dx, axret;写端口32位数io_out32:mov edx, [esp + 4]mov eax, [esp + 8]out dx, eaxret;读取标志寄存器的值io_load_eflags:pushfdpop eaxret;写入标志寄存器io_store_eflags:mov eax, [esp + 4]push eaxpopfdret;导出到C语言的接口,返回写入的地址范围描述符个数get_memory_block_count:mov eax, [dwMCRNumber] ;函数返回值一般存放在eax中ret;导出到C语言的接口,返回地址范围描述符缓冲区地址get_addr_buffer:mov eax, MemCheckBufretget_addr_buffer_int:mov eax, MemCheckBufret;导出到C语言的接口,返回全局描述符表首地址get_addr_gdt:mov eax, LABEL_GDTret;导出到C语言的接口,返回代码段首地址get_code32_addr:mov eax, LABEL_SEG_CODE32ret;导出到C语言的接口,装载任务状态段寄存器TRload_tr:LTR [esp + 4]rettaskswitch6:jmp 6*8:0rettaskswitch7:jmp 7*8:0rettaskswitch8:jmp 8*8:0rettaskswitch9:jmp 9*8:0retfarjmp:jmp FAR [esp + 4] ;写入eipretSegCode32Len equ $ - LABEL_SEG_CODE32[SECTION .data]ALIGN 32[BITS 32]MemCheckBuf: times 256 db 0dwMCRNumber: dd 0 ;记录BIOS总共向内存中写入多少个数据结构LABEL_SYSTEM_FONT:%include "fontData.inc"SystemFontLength equ $ - LABEL_SYSTEM_FONT ;导入字体二进制数据[SECTION .gs]ALIGN 32[BITS 32]LABEL_STACK:times 512 db 0TopOfStack1 equ $ - LABEL_STACKtimes 512 db 0TopOfStack2 equ $ - LABEL_STACKLenOfStackSection equ $ - LABEL_STACK
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。