asmfuncs.asm
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· 汇编 代码 · 共 656 行 · 第 1/2 页
ASM
656 行
cmp ExceptionNumber, EXCPT64_SEG_NOT_PRESENT
jz ExtraPushOne
cmp ExceptionNumber, EXCPT64_STACK_FAULT
jz ExtraPushOne
cmp ExceptionNumber, EXCPT64_GP_FAULT
jz ExtraPushOne
cmp ExceptionNumber, EXCPT64_PAGE_FAULT
jz ExtraPushOne
cmp ExceptionNumber, EXCPT64_ALIGNMENT_CHECK
jz ExtraPushOne
mov ExtraPush, 0
mov ExceptData, 0
jmp ExtraPushDone
ExtraPushOne:
mov ExtraPush, 1
;; If there's some extra data, save it also, and modify the saved AppRsp to effectively
;; pop this value off the application's stack.
mov rax, AppRsp
mov rbx, [rax]
mov ExceptData, rbx
add rax, 8
mov AppRsp, rax
ExtraPushDone:
;; The "push" above pushed the debug stack rsp. Since what we're actually doing
;; is building the context record on the debug stack, we need to save the pushed
;; debug RSP, and replace it with the application's last stack entry...
mov rax, [rsp + 24]
mov DebugRsp, rax
mov rax, AppRsp
add rax, 40
; application stack has ss, rsp, rflags, cs, & rip, so
; last actual application stack entry is
; 40 bytes into the application stack.
mov [rsp + 24], rax
;; continue building context record
;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
mov rax, ss
push rax
; CS from application is one entry back in application stack
mov rax, AppRsp
movzx rax, word ptr [rax + 8]
push rax
mov rax, ds
push rax
mov rax, es
push rax
mov rax, fs
push rax
mov rax, gs
push rax
;; UINT64 Rip;
; Rip from application is on top of application stack
mov rax, AppRsp
push qword ptr [rax]
;; UINT64 Gdtr[2], Idtr[2];
push 0
push 0
sidt fword ptr [rsp]
push 0
push 0
sgdt fword ptr [rsp]
;; UINT64 Ldtr, Tr;
xor rax, rax
str ax
push rax
sldt ax
push rax
;; UINT64 RFlags;
;; Rflags from application is two entries back in application stack
mov rax, AppRsp
push qword ptr [rax + 16]
;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
;; insure FXSAVE/FXRSTOR is enabled in CR4...
;; ... while we're at it, make sure DE is also enabled...
mov rax, cr8
push rax
mov rax, cr4
or rax, 208h
mov cr4, rax
push rax
mov rax, cr3
push rax
mov rax, cr2
push rax
push 0
mov rax, cr0
push rax
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
mov rax, dr7
push rax
;; clear Dr7 while executing debugger itself
xor rax, rax
mov dr7, rax
mov rax, dr6
push rax
;; insure all status bits in dr6 are clear...
xor rax, rax
mov dr6, rax
mov rax, dr3
push rax
mov rax, dr2
push rax
mov rax, dr1
push rax
mov rax, dr0
push rax
;; FX_SAVE_STATE_X64 FxSaveState;
sub rsp, 512
mov rdi, rsp
; IMPORTANT!! The debug stack has been carefully constructed to
; insure that rsp and rdi are 16 byte aligned when we get here.
; They MUST be. If they are not, a GP fault will occur.
FXSTOR_RDI
;; UINT64 ExceptionData;
mov rax, ExceptData
push rax
; call to C code which will in turn call registered handler
; pass in the vector number
mov rdx, rsp
mov rcx, ExceptionNumber
sub rsp, 40
call InterruptDistrubutionHub
add rsp, 40
; restore context...
;; UINT64 ExceptionData;
add rsp, 8
;; FX_SAVE_STATE_X64 FxSaveState;
mov rsi, rsp
FXRSTOR_RSI
add rsp, 512
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
pop rax
mov dr0, rax
pop rax
mov dr1, rax
pop rax
mov dr2, rax
pop rax
mov dr3, rax
;; skip restore of dr6. We cleared dr6 during the context save.
add rsp, 8
pop rax
mov dr7, rax
;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
pop rax
mov cr0, rax
add rsp, 8
pop rax
mov cr2, rax
pop rax
mov cr3, rax
pop rax
mov cr4, rax
pop rax
mov cr8, rax
;; UINT64 RFlags;
mov rax, AppRsp
pop qword ptr [rax + 16]
;; UINT64 Ldtr, Tr;
;; UINT64 Gdtr[2], Idtr[2];
;; Best not let anyone mess with these particular registers...
add rsp, 48
;; UINT64 Rip;
pop qword ptr [rax]
;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
;; NOTE - modified segment registers could hang the debugger... We
;; could attempt to insulate ourselves against this possibility,
;; but that poses risks as well.
;;
pop rax
; mov gs, rax
pop rax
; mov fs, rax
pop rax
mov es, rax
pop rax
mov ds, rax
mov rax, AppRsp
pop qword ptr [rax + 8]
pop rax
mov ss, rax
;; The next stuff to restore is the general purpose registers that were pushed
;; using the "push" instruction.
;;
;; The value of RSP as stored in the context record is the application RSP
;; including the 5 entries on the application stack caused by the exception
;; itself. It may have been modified by the debug agent, so we need to
;; determine if we need to relocate the application stack.
mov rbx, [rsp + 24] ; move the potentially modified AppRsp into rbx
mov rax, AppRsp
add rax, 40
cmp rbx, rax
je NoAppStackMove
mov rax, AppRsp
mov rcx, [rax] ; RIP
mov [rbx], rcx
mov rcx, [rax + 8] ; CS
mov [rbx + 8], rcx
mov rcx, [rax + 16] ; RFLAGS
mov [rbx + 16], rcx
mov rcx, [rax + 24] ; RSP
mov [rbx + 24], rcx
mov rcx, [rax + 32] ; SS
mov [rbx + 32], rcx
mov rax, rbx ; modify the saved AppRsp to the new AppRsp
mov AppRsp, rax
NoAppStackMove:
mov rax, DebugRsp ; restore the DebugRsp on the debug stack
; so our "pop" will not cause a stack switch
mov [rsp + 24], rax
cmp ExceptionNumber, 068h
jne NoChain
Chain:
;; Restore rflags so when we chain, the flags will be exactly as if we were never here.
;; We gin up the stack to do an iretq so we can get ALL the flags.
mov rax, AppRsp
mov rbx, [rax + 40]
push rbx
mov rax, ss
push rax
mov rax, rsp
add rax, 16
push rax
mov rax, AppRsp
mov rbx, [rax + 16]
and rbx, NOT 300h ; special handling for IF and TF
push rbx
mov rax, cs
push rax
mov rax, offset PhonyIretq
push rax
iretq
PhonyIretq:
;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
pop rdi
pop rsi
pop rbp
pop rsp
pop rbx
pop rdx
pop rcx
pop rax
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
;; Switch back to application stack
mov rsp, AppRsp
;; Jump to original handler
jmp OrigVector
NoChain:
;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
pop rdi
pop rsi
pop rbp
pop rsp
pop rbx
pop rdx
pop rcx
pop rax
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
;; Switch back to application stack
mov rsp, AppRsp
;; We're outa here...
iretq
text ENDS
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?