efi32.asm
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· 汇编 代码 · 共 582 行 · 第 1/2 页
ASM
582 行
;------------------------------------------------------------------------------
;*
;* Copyright 2006, Intel Corporation
;* All rights reserved. This program and the accompanying materials
;* are licensed and made available under the terms and conditions of the BSD License
;* which accompanies this distribution. The full text of the license may be found at
;* http://opensource.org/licenses/bsd-license.php
;*
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;*
;* efi32.asm
;*
;* Abstract:
;*
;------------------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Now in 32-bit protected mode.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.486
.model flat
.stack
.code
org 21000h
DEFAULT_HANDLER_SIZE EQU INT1 - INT0
JmpCommonIdtEntry macro
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
; using a 8 bit reletive jump when the entries are
; within 255 bytes of the common entry. This must
; be done to maintain the consistency of the size
; of entry points...
db 0e9h ; jmp 16 bit relative
dd commonIdtEntry - $ - 4 ; offset to jump to
endm
Start:
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0001ffff0h
call ClearScreen
; Populate IDT with meaningful offsets for exception handlers...
sidt fword ptr [Idtr] ; get fword address of IDT
mov eax, offset Halt
mov ebx, eax ; use bx to copy 15..0 to descriptors
shr eax, 16 ; use ax to copy 31..16 to descriptors
mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
mov esi, [offset Idtr + 2]
mov edi, [esi]
@@: ; loop through all IDT entries exception handlers and initialize to default handler
mov word ptr [edi], bx ; write bits 15..0 of offset
mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
mov word ptr [edi+6], ax ; write bits 31..16 of offset
add edi, 8 ; move up to next descriptor
add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
loop @b ; loop back through again until all descriptors are initialized
;; at this point edi contains the offset of the descriptor for INT 20
;; and bx contains the low 16 bits of the offset of the default handler
;; so initialize all the rest of the descriptors with these two values...
; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
;@@: ; loop through all IDT entries exception handlers and initialize to default handler
; mov word ptr [edi], bx ; write bits 15..0 of offset
; mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
; mov word ptr [edi+6], ax ; write bits 31..16 of offset
; add edi, 8 ; move up to next descriptor
; loop @b ; loop back through again until all descriptors are initialized
;; DUMP location of IDT and several of the descriptors
; mov ecx, 8
; mov eax, [offset Idtr + 2]
; mov eax, [eax]
; mov edi, 0b8000h
; call PrintDword
; mov esi, eax
; mov edi, 0b80a0h
; jmp OuterLoop
;;
;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
; mov eax, 011111111h
; mov ebx, 022222222h
; mov ecx, 033333333h
; mov edx, 044444444h
; mov ebp, 055555555h
; mov esi, 066666666h
; mov edi, 077777777h
; push 011111111h
; push 022222222h
; push 033333333h
; int 119
mov esi,022000h ; esi = 22000
mov eax,[esi+014h] ; eax = [22014]
add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
add ebp,esi
mov edi,[ebp+034h] ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase
mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
add eax,edi ; eax = ImageBase + EntryPoint
mov dword ptr [EfiLdrOffset],eax ; Modify far jump instruction for correct entry point
mov bx,word ptr[ebp+6] ; bx = Number of sections
xor eax,eax
mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
add ebp,eax
add ebp,018h ; ebp = Start of 1st Section
SectionLoop:
push esi ; Save Base of EFILDR.C
push edi ; Save ImageBase
add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
mov ecx,[ebp+010h] ; ecs = SizeOfRawData
cld
shr ecx,2
rep movsd
pop edi ; Restore ImageBase
pop esi ; Restore Base of EFILDR.C
add bp,028h ; ebp = ebp + 028h = Pointer to next section record
dec bx
cmp bx,0
jne SectionLoop
movzx eax, word ptr [Idtr] ; get size of IDT
inc eax
add eax, dword ptr [Idtr + 2] ; add to base of IDT to get location of memory map...
push eax ; push memory map location on stack for call to EFILDR...
push eax ; push return address (useless, just for stack balance)
db 0b8h
EfiLdrOffset:
dd 000401000h ; Offset of EFILDR
; mov eax, 401000h
push eax
ret
; db "**** DEFAULT IDT ENTRY ***",0
align 02h
Halt:
INT0:
push 0h ; push error code place holder on the stack
push 0h
JmpCommonIdtEntry
; db 0e9h ; jmp 16 bit reletive
; dd commonIdtEntry - $ - 4 ; offset to jump to
INT1:
push 0h ; push error code place holder on the stack
push 1h
JmpCommonIdtEntry
INT2:
push 0h ; push error code place holder on the stack
push 2h
JmpCommonIdtEntry
INT3:
push 0h ; push error code place holder on the stack
push 3h
JmpCommonIdtEntry
INT4:
push 0h ; push error code place holder on the stack
push 4h
JmpCommonIdtEntry
INT5:
push 0h ; push error code place holder on the stack
push 5h
JmpCommonIdtEntry
INT6:
push 0h ; push error code place holder on the stack
push 6h
JmpCommonIdtEntry
INT7:
push 0h ; push error code place holder on the stack
push 7h
JmpCommonIdtEntry
INT8:
; Double fault causes an error code to be pushed so no phony push necessary
nop
nop
push 8h
JmpCommonIdtEntry
INT9:
push 0h ; push error code place holder on the stack
push 9h
JmpCommonIdtEntry
INT10:
; Invalid TSS causes an error code to be pushed so no phony push necessary
nop
nop
push 10
JmpCommonIdtEntry
INT11:
; Segment Not Present causes an error code to be pushed so no phony push necessary
nop
nop
push 11
JmpCommonIdtEntry
INT12:
; Stack fault causes an error code to be pushed so no phony push necessary
nop
nop
push 12
JmpCommonIdtEntry
INT13:
; GP fault causes an error code to be pushed so no phony push necessary
nop
nop
push 13
JmpCommonIdtEntry
INT14:
; Page fault causes an error code to be pushed so no phony push necessary
nop
nop
push 14
JmpCommonIdtEntry
INT15:
push 0h ; push error code place holder on the stack
push 15
JmpCommonIdtEntry
INT16:
push 0h ; push error code place holder on the stack
push 16
JmpCommonIdtEntry
INT17:
; Alignment check causes an error code to be pushed so no phony push necessary
nop
nop
push 17
JmpCommonIdtEntry
INT18:
push 0h ; push error code place holder on the stack
push 18
JmpCommonIdtEntry
INT19:
push 0h ; push error code place holder on the stack
push 19
JmpCommonIdtEntry
INTUnknown:
REPEAT (78h - 20)
push 0h ; push error code place holder on the stack
; push xxh ; push vector number
db 06ah
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
JmpCommonIdtEntry
ENDM
commonIdtEntry:
pushad
mov ebp, esp
;;
;; At this point the stack looks like this:
;;
;; eflags
;; Calling CS
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?