37extern vxInterruptHandler
39; Stack layout at int_common entry:
40; [rsp+ 0] = error code (pushed by isr macro or CPU)
41; [rsp+ 8] = int number (pushed by isr macro)
42; [rsp+16] = RIP (pushed by CPU)
43; [rsp+24] = CS (pushed by CPU) <-- ring check
45; [rsp+40] = RSP (only on privilege change)
46; [rsp+48] = SS (only on privilege change)
49 ; CS is at [rsp+24] before pushall
50 test qword [rsp+24], 3
56 ; After pushall: 15 regs * 8 = 120 bytes pushed
57 ; CS is now at [rsp + 120 + 24] = [rsp+144]
59 mov rbx, rsp ; rbx = pointer to saved-regs frame (interrupt_stack_frame_t)
61 ; Disable x87 EM + TS so fxsave doesn't #NM
63 and rax, ~((1 << 2) | (1 << 3))
66 ; Allocate 512-byte fxsave buffer, 64-byte aligned (safe for fxsave/xsave)
71 mov rdi, rbx ; arg1: interrupt_stack_frame_t*
72 mov rsi, rsp ; arg2: fxsave area* (optional, can be ignored in handler)
73 call vxInterruptHandler
75 fxrstor [rsp] ; restore FPU — rsp unchanged since fxsave
77 mov rsp, rbx ; restore to post-pushall stack position
81 ; CS is at [rsp+24] again (same layout as entry, before pushall)
82 test qword [rsp+24], 3
86 add rsp, 16 ; discard error code + int number
92%if !(%1 == 8 || (%1 >= 10 && %1 <= 14) || %1 == 17 || %1 == 21 || %1 == 29 || %1 == 30)