;RCX: 1st integer argument ;RDX: 2nd integer argument ;R8: 3rd integer argument ;R9: 4th integer argument CALLBACK struct A qword ? S qword ? CALLBACK ends ASMENTRY_STACK struct ;keep this 16 byte aligned Scratchspace qword ? ;0 Scratchspace2 qword ? ;8 Scratchspace3 qword ? ;0 Scratchspace4 qword ? ;8 Originalmxcsr qword ? OriginalRAX qword ? OriginalRBX qword ? OriginalRCX qword ? OriginalRDX qword ? OriginalRSI qword ? OriginalRDI qword ? OriginalRBP qword ? OriginalRSP qword ? ;not really 'original' OriginalR8 qword ? OriginalR9 qword ? OriginalR10 qword ? OriginalR11 qword ? OriginalR12 qword ? OriginalR13 qword ? OriginalR14 qword ? OriginalR15 qword ? OriginalES qword ? OriginalDS qword ? OriginalSS qword ? ASMENTRY_STACK ends _TEXT SEGMENT 'CODE' EXTERN perfmon_interrupt_centry : proc EXTERN perfmonJumpBackLocation : CALLBACK PUBLIC perfmon_interrupt perfmon_interrupt: ;save stack position cld push 0 ;push an errorcode on the stack so the stackindex enum type can stay the same relative to interrupts that do have an errorcode (int 14) ;stack is aligned at this point sub rsp, 4096 sub rsp,SIZEOF ASMENTRY_STACK mov (ASMENTRY_STACK PTR [rsp]).OriginalRBP,rbp lea rbp,(ASMENTRY_STACK PTR [rsp]).OriginalRAX ;make rbp point to the start of the structure mov (ASMENTRY_STACK PTR [rsp]).OriginalRAX,rax mov (ASMENTRY_STACK PTR [rsp]).OriginalRBX,rbx mov (ASMENTRY_STACK PTR [rsp]).OriginalRCX,rcx mov (ASMENTRY_STACK PTR [rsp]).OriginalRDX,rdx mov (ASMENTRY_STACK PTR [rsp]).OriginalRSI,rsi mov (ASMENTRY_STACK PTR [rsp]).OriginalRDI,rdi mov (ASMENTRY_STACK PTR [rsp]).OriginalRSP,rsp mov (ASMENTRY_STACK PTR [rsp]).OriginalR8,r8 mov (ASMENTRY_STACK PTR [rsp]).OriginalR9,r9 mov (ASMENTRY_STACK PTR [rsp]).OriginalR10,r10 mov (ASMENTRY_STACK PTR [rsp]).OriginalR11,r11 mov (ASMENTRY_STACK PTR [rsp]).OriginalR12,r12 mov (ASMENTRY_STACK PTR [rsp]).OriginalR13,r13 mov (ASMENTRY_STACK PTR [rsp]).OriginalR14,r14 mov (ASMENTRY_STACK PTR [rsp]).OriginalR15,r15 mov ax,ds mov word ptr (ASMENTRY_STACK PTR [rsp]).OriginalDS,ax mov ax,es mov word ptr (ASMENTRY_STACK PTR [rsp]).OriginalES,ax mov ax,ss mov word ptr (ASMENTRY_STACK PTR [rsp]).OriginalSS,ax mov ax,2bh mov ds,ax mov es,ax mov ax,18h mov ss,ax cmp qword ptr [rbp+8*21+4096],010h ;check if origin is in kernelmode (check ss) je skipswap1 ;if so, skip the swapgs swapgs ;swap gs with the kernel version (not to self fix when called from inside kernel) skipswap1: stmxcsr dword ptr (ASMENTRY_STACK PTR [rsp]).Originalmxcsr mov (ASMENTRY_STACK PTR [rsp]).scratchspace,1f80h ldmxcsr dword ptr (ASMENTRY_STACK PTR [rsp]).scratchspace ;mov rcx,rbp call perfmon_interrupt_centry ldmxcsr dword ptr (ASMENTRY_STACK PTR [rsp]).Originalmxcsr cmp qword ptr [rbp+8*21+4096],10h ;was it a kernelmode interrupt ? je skipswap2 ;if so, skip the swapgs part swapgs ;swap back skipswap2: cmp al,1 ;restore state mov ax,word ptr (ASMENTRY_STACK PTR [rsp]).OriginalDS mov ds,ax mov ax,word ptr (ASMENTRY_STACK PTR [rsp]).OriginalES mov es,ax mov ax,word ptr (ASMENTRY_STACK PTR [rsp]).OriginalSS mov ss,ax mov rax,(ASMENTRY_STACK PTR [rsp]).OriginalRAX mov rbx,(ASMENTRY_STACK PTR [rsp]).OriginalRBX mov rcx,(ASMENTRY_STACK PTR [rsp]).OriginalRCX mov rdx,(ASMENTRY_STACK PTR [rsp]).OriginalRDX mov rsi,(ASMENTRY_STACK PTR [rsp]).OriginalRSI mov rdi,(ASMENTRY_STACK PTR [rsp]).OriginalRDI mov r8,(ASMENTRY_STACK PTR [rsp]).OriginalR8 mov r9,(ASMENTRY_STACK PTR [rsp]).OriginalR9 mov r10,(ASMENTRY_STACK PTR [rsp]).OriginalR10 mov r11,(ASMENTRY_STACK PTR [rsp]).OriginalR11 mov r12,(ASMENTRY_STACK PTR [rsp]).OriginalR12 mov r13,(ASMENTRY_STACK PTR [rsp]).OriginalR13 mov r14,(ASMENTRY_STACK PTR [rsp]).OriginalR14 mov r15,(ASMENTRY_STACK PTR [rsp]).OriginalR15 je skip_original_perfmon jmp skip_original_perfmon ;stack unwind mov rbp,(ASMENTRY_STACK PTR [rsp]).OriginalRBP add rsp,SIZEOF ASMENTRY_STACK ;+8 for the push 0 add rsp,8 add rsp,4096 jmp [perfmonJumpBackLocation.A] ;<-works fine skip_original_perfmon: ;stack unwind mov rbp,(ASMENTRY_STACK PTR [rsp]).OriginalRBP add rsp,SIZEOF ASMENTRY_STACK ;+8 for the push 0 add rsp,4096 add rsp,8 ;jump to when the stack has been completly restored to what it was at interrupt time ;push rax ;push rbx ;unmask the perfmon interrupt ;mov rax,0fffffffffffe0330h ;mov rbx,[rax] ;and rbx,0ffh ;mov [rax],rbx ;End of interrupt ;mov rax,0fffffffffffe00b0h ;xor rbx,rbx ;mov [rax],rbx ;set EOI to 0 ;pop rbx ;pop rax iretq _TEXT ENDS END