xref: /reactos/sdk/lib/ucrt/inc/kxamd64.inc (revision fe93a3f9)
1
2;++
3;
4; Copyright (c) Microsoft Corporation.  All rights reserved.
5;
6;
7; Module:
8;
9;   kxamd64.w
10;
11; Astract:
12;
13;   Contains AMD64 architecture constants and assembly macros.
14;
15;
16;--
17
18include macamd64.inc
19
20;
21; If the actual CFG dispatch code is not being assembled, then declare the
22; guard dispatch function as external.
23;
24
25ifdef CAPXCALL_VIA_CFG
26ifndef CFG_ASM
27
28        extern  _guard_dispatch_icall:proc
29
30endif ; CFG_ASM
31endif
32
33;
34;
35
36;
37; Retpoline macros
38;
39
40RETPOLINEDIRECTIVE macro RetpolineType
41
42ifdef _RETPOLINE
43    ifidn <RetpolineType>,<RetpolineRax>
44    .retpolinerax
45    elseifidn <RetpolineType>,<RetpolineSwitchTable>
46    .retpolineswitchtable
47    elseifidn <RetpolineType>,<RetpolineImport>
48    .retpolineimport
49    elseifidn <RetpolineType>,<RetpolineCfgDispatch>
50    .retpolineguardicall
51    elseifidn <RetpolineType>,<RetpolineIgnore>
52    .retpolineignore
53    elseifnb <RetpolineType>
54    .err @catstr(<Invalid retpoline type >, <RetpolineType>)
55    endif
56endif ; _RETPOLINE
57
58    ENDM
59
60;
61; IceCAP macros
62;
63
64ifdef _CAPKERN
65
66;
67; Define kernel icecap macros for tracing assembly routines.
68;
69
70        extern  __CAP_Start_DirectCall_Profiling_ASM:proc
71        extern  __CAP_Start_IndirectCall_Profiling_ASM:proc
72        extern  __CAP_Start_DirectCall_Tail_Profiling_ASM:proc
73        extern  __CAP_Start_IndirectCall_Tail_Profiling_ASM:proc
74        extern  __CAP_Start_DirectJmp_Profiling_ASM:proc
75        extern  __CAP_Start_IndirectJmp_Profiling_ASM:proc
76        extern  __CAP_End_Profiling:proc
77
78endif ; _CAPKERN
79
80;
81; CAPDCALL - Perform an IceCAP instrumented direct function call.
82;
83;            Do NOT use this macro directly. Use CAPCALL instead.
84;
85;            Instrumenation is disabled on non-IceCAP builds.
86;
87; Arguments:
88;
89;   Callee - A function label.
90;
91;   NoRet - If set, the function does not return to the caller.
92;
93; Return value:
94;
95;   Returns the value of the function specified by Callee.
96;
97
98CAPDCALL macro Callee, NoRet
99
100ifdef _CAPKERN
101
102ifnb <NoRet>
103
104        call    __CAP_Start_DirectCall_Tail_Profiling_ASM ; record profiling information
105
106else
107
108        call    __CAP_Start_DirectCall_Profiling_ASM ; record profiling information
109
110endif
111
112endif ; _CAPKERN
113
114        call    Callee
115
116ifdef _CAPKERN
117
118ifb <NoRet>
119
120        call    __CAP_End_Profiling       ; record profiling information
121
122endif
123
124endif ; _CAPKERN
125
126        endm
127
128;
129; CAPICALL - Perform an IceCAP instrumented indirect function call.
130;
131;            Do NOT use this macro directly. Use CAPCALL instead.
132;
133;            Instrumenation is disabled on non-IceCAP builds.
134;
135; Arguments:
136;
137;   Callee - A register or a memory location.
138;
139;   NoRet - If set, the function does not return to the caller.
140;
141; Return value:
142;
143;   Returns the value of the function specified by Callee.
144;
145
146CAPICALL macro Callee, NoRet, RetpolineType
147
148ifdef _CAPKERN
149
150ifnb <NoRet>
151
152        call    __CAP_Start_IndirectCall_Tail_Profiling_ASM ; record profiling information
153
154else
155
156        call    __CAP_Start_IndirectCall_Profiling_ASM ; record profiling information
157
158endif
159
160endif ; _CAPKERN
161
162        RETPOLINEDIRECTIVE RetpolineType
163
164        call    Callee
165
166
167ifdef _CAPKERN
168
169ifb <NoRet>
170
171        call    __CAP_End_Profiling       ; record profiling information
172
173endif
174
175endif ; _CAPKERN
176
177        endm
178
179;
180; CAPXCALL - Perform a CFG IceCAP instrumented indirect function call.
181;
182;            This macro MUST be used to call CFG checked functions.
183;
184;            Instrumenation is disabled on non-IceCAP builds.
185;
186; Arguments:
187;
188;   Callee - A register or a memory location.
189;
190;   NoRet - If set, the function does not return to the caller.
191;
192; Return value:
193;
194;   Returns the value of the function specified by Callee.
195;
196
197CAPXCALL macro Callee, NoRet
198
199ifdifi  <Callee>, <rax>
200
201        mov     rax, Callee
202
203endif
204
205ifdef CAPXCALL_VIA_CFG
206
207        CAPDCALL _guard_dispatch_icall, <NoRet>
208
209else
210
211        CAPICALL     rax, <NoRet>, RetpolineRax
212endif
213
214        endm
215
216;
217; CAPCALL - Perform an IceCAP instrumented function call.
218;
219;           Instrumenation is disabled on non-IceCAP builds.
220;
221; Arguments:
222;
223;   Callee - A function label, a register, or a memory location.
224;
225;   NoRet - If set, the function does not return to the caller.
226;
227; Return value:
228;
229;   Returns the value of the function specified by Callee.
230;
231
232CAPCALL macro Callee, NoRet, RetpolineType
233
234;
235; The documentation surrounding the .type operator is very poor.
236; Here is the significance of each of the bits.
237;
238; 0 - References a label in the code segment if set.
239; 1 - References a memory variable or relocatable data object if set.
240; 2 - Is an immediate (absolute/constant) value if set.
241; 3 - Uses direct memory addressing if set.
242; 4 - Is a register name, if set.
243; 5 - References no undefined symbols and there is no error, if set.
244; 6 - Is an SS: relative reference, if set.
245; 7 - References an external name.
246;
247
248if (.type(Callee)) eq 000h ; direct via local label
249
250        CAPDCALL Callee, NoRet
251
252elseif (.type(Callee)) eq 022h ; register-direct call
253
254        CAPICALL Callee, NoRet, RetpolineType
255
256elseif (.type(Callee)) eq 025h ; direct via extern proc
257
258        CAPDCALL Callee, NoRet
259
260elseif (.type(Callee)) eq 030h ; register-indirect call
261
262        CAPICALL Callee, NoRet, RetpolineType
263
264elseif (.type(Callee)) eq 062h ; indirect via offset from register
265
266        CAPICALL Callee, NoRet, RetpolineType
267
268elseif (.type(Callee)) eq 0A5h ; direct via extern proc
269
270        CAPDCALL Callee, NoRet
271
272elseif (.type(Callee)) eq 0AAh ; indirect via extern qword
273
274        CAPICALL Callee, NoRet, RetpolineType
275
276else
277
278        .err @catstr(<unknown expression type >, %(.type(Callee)))
279
280endif
281
282        endm
283
284;
285; CAPJMP - Perform an IceCAP instrumented tail jump.
286;
287;          Instrumenation is disabled on non-IceCAP builds.
288;
289; Arguments:
290;
291;   Callee - A function label, a memory address, or a register.
292;
293; Return value:
294;
295;   Never returns.
296;
297
298CAPJMP macro Callee, RetpolineType
299
300;
301; Begin jump instrumentation
302;
303
304ifdef _CAPKERN
305
306;
307; The documentation surrounding the .type operator is very poor.
308; See above for syntax explanation.
309;
310
311if (.type(Callee)) eq 000h ; direct via local label
312
313        call    __CAP_Start_DirectJmp_Profiling_ASM ; record profiling information
314
315elseif (.type(Callee)) eq 022h ; register-direct jump
316
317        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
318
319elseif (.type(Callee)) eq 025h ; direct via extern proc
320
321        call    __CAP_Start_DirectJmp_Profiling_ASM ; record profiling information
322
323elseif (.type(Callee)) eq 030h ; register-indirect
324
325        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
326
327elseif (.type(Callee)) eq 062h ; indirect via offset from register
328
329        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
330
331elseif (.type(Callee)) eq 0A5h ; direct via extern proc
332
333        call    __CAP_Start_DirectJmp_Profiling_ASM ; record profiling information
334
335elseif (.type(Callee)) eq 0AAh ; indirect via extern qword
336
337        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
338
339else
340
341        .err @catstr(<unknown expression type >, %(.type(Callee)))
342
343endif
344
345endif ; _CAPKERN
346
347;
348; End jump instrumentation. Begin common code.
349;
350
351        RETPOLINEDIRECTIVE <RetpolineType>
352
353        jmp     Callee
354
355        endm
356
357;
358; CAPRETPOLJMP - Perform an IceCAP instrumented tail jump using retpoline.
359;
360;          Instrumentation is disabled on non-IceCAP builds.
361;
362; Arguments:
363;
364;   Callee - A function label, a memory address or a register.
365;
366; Return value:
367;
368;   Never returns.
369;
370
371CAPRETPOLJMP macro Callee, Alignment
372
373        LOCAL Jump
374
375;
376; Begin jump instrumentation
377;
378
379ifdef _CAPKERN
380
381;
382; The documentation surrounding the .type operator is very poor.
383; See above for syntax explanation.
384;
385
386if (.type(Callee)) eq 000h ; direct via local label
387
388        call    __CAP_Start_DirectJmp_Profiling_ASM ; record profiling information
389
390elseif (.type(Callee)) eq 022h ; register-direct jump
391
392        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
393
394elseif (.type(Callee)) eq 025h ; direct via extern proc
395
396        call    __CAP_Start_DirectJmp_Profiling_ASM ; record profiling information
397
398elseif (.type(Callee)) eq 030h ; register-indirect
399
400        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
401
402elseif (.type(Callee)) eq 062h ; indirect via offset from register
403
404        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
405
406elseif (.type(Callee)) eq 0A5h ; direct via extern proc
407
408        call    __CAP_Start_DirectJmp_Profiling_ASM ; record profiling information
409
410elseif (.type(Callee)) eq 0AAh ; indirect via extern qword
411
412        call    __CAP_Start_IndirectJmp_Profiling_ASM  ; record profiling information
413
414else
415
416        .err @catstr(<unknown expression type >, %(.type(Callee)))
417
418endif
419
420endif ; _CAPKERN
421
422;
423; End jump instrumentation. Begin common code.
424;
425
426        call Jump
427        int  3
428
429ifnb <Alignment>
430        ALIGN Alignment
431else
432        ALIGN 16
433endif
434
435Jump:
436        mov [rsp], Callee
437        ret
438
439        endm
440
441;
442; CAPEPILOGJMP - Logs a tail jump from an epilog.
443;
444;                Instrumenation is disabled on non-IceCAP builds.
445;
446; Arguments:
447;
448;   Callee - A function label, a memory address, or a register.
449;
450; Return value:
451;
452;   None
453;
454
455CAPEPILOGJMP macro Callee
456
457        LOCAL Exit
458
459ifdef _CAPKERN
460
461        jmp Exit
462Exit:
463        CAPJMP Callee
464
465else
466
467        jmp Callee
468
469endif ; _CAPKERN
470
471        endm
472
473;
474; CAPREX_JMP_REG  - Perform an IceCAP instrumented indirect tail jump.
475;                   Use this when a function does not return to the caller
476;                   and when a rex_jmp_reg would normally be specified.
477;
478;                   Instrumentation is disabled on non-IceCAP builds.
479;
480; Arguments:
481;
482;   Callee is a register or memory location.
483;
484; Return value:
485;
486;   None
487;
488
489CAPREX_JMP_REG macro Callee, RetpolineType
490
491ifdef _CAPKERN
492
493        call    __CAP_Start_IndirectJmp_Profiling_ASM ; record profiling information
494
495endif ; _CAPKERN
496
497        RETPOLINEDIRECTIVE <RetpolineType>
498        rex_jmp_reg Callee                    ; make the jump
499        endm
500
501;
502; Define macro to clear legacy floating exceptions.
503;
504
505clfpex  macro
506
507        db      0dbh, 0e2h
508
509        endm
510
511;
512; Define macro to perform an enlightened yield.
513;
514; Arguments:
515;
516;   None.
517;
518; N.B. This macro is restricted to only freely using the register specified by
519;      the 'Register' parameter and rcx. 'Register' should be nonvolatile.
520;
521
522EnlightenedYield macro Register
523
524        local skip
525
526;
527;;
528
529skip:   Yield
530
531        endm
532
533;
534; Define macro to acquire spin lock.
535;
536; Arguments:
537;
538;   None.
539;
540; N.B. This macro is restricted to only freely using the register specified by
541;      the 'Register' parameter and rcx. 'Register' should be nonvolatile.
542;
543; N.B. If 'Register' is specified, 'Address' must be nonvolatile or global.
544;
545
546AcquireSpinLock macro Address, Register
547
548        local exit, spin
549
550ifndef NT_UP
551
552   lock bts     qword ptr Address, 0    ; attempt to acquire spin lock
553        jnc     short exit              ; if nc, spin lock acquired
554
555ifndef XBOX_SYSTEMOS
556
557ifnb <Register>
558
559        xor      Register, Register      ; initialize spin count
560
561endif
562
563endif
564
565spin:   EnlightenedYield <Register>     ; yield execution
566        test    qword ptr Address, 1    ; check if lock currently owned
567        jnz     short spin              ; if nz, spin lock owned
568   lock bts     qword ptr Address, 0    ; attempt to acquire spin lock
569        jc      short spin              ; if c, spin lock owned
570
571exit:                                   ; continue
572
573endif
574
575        endm
576
577;
578; Define macro to acquire spin lock and mask interrupts.
579;
580; Arguments:
581;
582;   None.
583;
584; Note:
585;
586;   rsp is assumed to point to pushed EFLAGS
587;
588; N.B. This macro uses no registers.
589;
590
591AcquireSpinLockDisable macro Address
592
593        local exit, spin, spin1
594
595        cli                             ; disable interrupts
596
597ifndef NT_UP
598
599   lock bts     qword ptr Address, 0    ; attempt to acquire spin lock
600        jnc     short exit              ; if nc, spin lock acquired
601spin:   test    dword ptr [rsp], EFLAGS_IF_MASK ; test if interrupts enabled
602        jz      short spin1             ; if z, interrupts disabled
603        sti                             ; enable interrupts
604
605spin1:  Yield                           ; yield execution
606
607        test    qword ptr Address, 1    ; check if lock currently owned
608        jnz     short spin1             ; if nz, spin lock owned
609        cli                             ; lock is (was) clear, disable ints
610   lock bts     qword ptr Address, 0    ; attempt to acquire spin lock
611        jc      short spin              ; if c, spin lock owned
612exit:                                   ; continue
613
614endif
615
616        endm
617
618;
619; Define macro to release spin lock.
620;
621; Arguments:
622;
623;   None.
624;
625; N.B. This macro uses no registers.
626;
627
628ReleaseSpinLock macro Address
629
630ifndef NT_UP
631
632   lock and     qword ptr Address, 0    ; release spin lock
633
634endif
635
636        endm
637
638;
639; Define macro to release spin lock and restore the interrupt flag.
640;
641; Arguments:
642;
643;   None.
644;
645; Note:
646;
647;   rsp is assumed to point to pushd EFLAGS
648;
649; N.B. This macro uses no registers.
650;
651
652ReleaseSpinLockEnable macro Address
653
654        local exit
655
656ifndef NT_UP
657
658   lock and     qword ptr Address, 0    ; release spin lock
659
660endif
661
662        test    dword ptr [rsp], EFLAGS_IF_MASK ; test if interrupts enabled
663        jz      short exit              ; if z, interrupts not enabled
664        sti                             ; enable interrupts
665exit:                                   ; continue
666
667        endm
668
669;
670; Define macro to try to acquire spin lock.
671;
672; Arguments:
673;
674;   None.
675;
676; N.B. This macro uses no registers.
677;
678
679TryToAcquireSpinLock macro Address
680
681ifndef NT_UP
682
683        lock bts qword ptr Address, 0   ; attempt to acquire spin lock
684
685endif
686
687        endm
688
689;
690; Define macro to perform the equivalent of reading cr8.
691;
692; Arguments:
693;
694;   None
695;
696; The equivalent of the contents of cr8 is returned in rax
697;
698; N.B. This macro is restricted to using only rax.
699;
700
701ReadCr8 macro
702
703        mov     rax, cr8                ; read IRQL
704
705        endm
706
707;
708; Define macro to perform the equivalent of writing cr8.
709;
710; Arguments:
711;
712;   rcx - The desired value of cr8.
713;
714
715WriteCr8 macro
716
717        mov     cr8, rcx                ; write IRQL
718
719        endm
720
721;
722; Define macro to get current IRQL.
723;
724; Arguments:
725;
726;   None.
727;
728; The previous IRQL is returned in rax.
729;
730
731CurrentIrql macro
732
733        ReadCr8                         ; get current IRQL
734
735        endm
736
737;
738; Define macro to lower IRQL.
739;
740; Arguments:
741;
742;   rcx - Supplies the new IRQL.
743;
744; N.B. The register rax is destroyed.
745;
746; N.B. This macro is restricted to using only rcx and rdx.
747;
748
749LowerIrql macro
750
751        local   exit
752
753if DBG
754
755        mov     rdx, rax                ; preserve rax
756        ReadCr8                         ; get current IRQL
757        cmp     eax, ecx                ; check new IRQL
758        jge     short exit              ; if ge, new IRQL okay
759        int     3                       ; break into debugger
760exit:   mov     rax, rdx
761
762endif
763
764        WriteCr8                        ; set new IRQL
765
766        endm
767
768;
769; Define macro to raise IRQL.
770;
771; Arguments:
772;
773;   rcx - Supplies the new IRQL.
774;
775; The previous IRQL is returned in rax.
776;
777; N.B. This macro is restricted to using only rax and rcx.
778;
779
780RaiseIrql macro
781
782        local   exit
783
784        ReadCr8                         ; get current IRQL
785
786if DBG
787
788        cmp     eax, ecx                ; check new IRQL
789        jle     short exit              ; if le, new IRQL okay
790        int     3                       ; break into debugger
791
792endif
793
794exit:   WriteCr8                        ; set new IRQL
795
796        endm
797
798;
799; Define macro to set IRQL.
800;
801; Arguments:
802;
803;   rcx - Supplies the new IRQL.
804;
805; N.B. This macro is restricted to using only rcx.
806;
807
808SetIrql macro
809
810        WriteCr8                        ; set new IRQL
811
812        endm
813
814;
815; Define macro to swap IRQL.
816;
817; Arguments:
818;
819;   rcx - Supplies the new IRQL.
820;
821; The previous IRQL is returned in rax.
822;
823; N.B. This macro is restricted to using only rax and rcx.
824;
825
826SwapIrql macro
827
828        ReadCr8                         ; get current IRQL
829        WriteCr8                        ; set new IRQL
830
831        endm
832
833;
834;
835
836;
837; Define restore exception state macro.
838;
839;   This macro restores the nonvolatile state.
840;
841; Arguments:
842;
843;   Flag - If blank, then nonvolatile floating and integer registers are
844;       restored. If nonblank and identical to "Rbp", then rbp is restored
845;       in addition to the nonvolatile floating and integer registers. If
846;       nonblank and identical to "NoFp", then only the nonvolatile integer
847;       registers are restored.
848;
849; Implicit arguments:
850;
851;   rsp - Supplies the address of the exception frame.
852;
853
854RESTORE_EXCEPTION_STATE macro Flag
855
856        lea     rcx, 100h[rsp]          ; set frame display pointer
857
858ifdif <Flag>, <NoFp>
859
860        movaps  xmm6, ExXmm6[rsp]       ; restore nonvolatile xmm registers
861        movaps  xmm7, ExXmm7[rsp]       ;
862        movaps  xmm8, ExXmm8[rsp]       ;
863        movaps  xmm9, ExXmm9[rsp]       ;
864        movaps  xmm10, ExXmm10[rsp]     ;
865        movaps  xmm11, (ExXmm11 - 100h)[rcx] ;
866        movaps  xmm12, (ExXmm12 - 100h)[rcx] ;
867        movaps  xmm13, (ExXmm13 - 100h)[rcx] ;
868        movaps  xmm14, (ExXmm14 - 100h)[rcx] ;
869        movaps  xmm15, (ExXmm15 - 100h)[rcx] ;
870
871endif
872
873        mov     rbx, (ExRbx - 100h)[rcx] ; restore nonvolatile integer registers
874        mov     rdi, (ExRdi - 100h)[rcx] ;
875        mov     rsi, (ExRsi - 100h)[rcx] ;
876        mov     r12, (ExR12 - 100h)[rcx] ;
877        mov     r13, (ExR13 - 100h)[rcx] ;
878        mov     r14, (ExR14 - 100h)[rcx] ;
879        mov     r15, (ExR15 - 100h)[rcx] ;
880
881ifdif <Flag>, <NoPop>
882
883ifidn <Flag>, <Rbp>
884
885        mov     rbp, (ExRbp - 100h)[rcx]  ; restore nonvolatile integer register
886
887endif
888
889        add     rsp, KEXCEPTION_FRAME_LENGTH - (1 * 8) ; deallocate frame
890
891ifdif <Flag>, <Rbp>
892
893        BEGIN_EPILOGUE
894
895endif
896
897endif
898
899        endm
900
901;
902; Define generate exception frame macro.
903;
904;   This macro allocates an exception frame and saves the nonvolatile state.
905;
906; Arguments:
907;
908;   Flag - If blank, then nonvolatile floating and integer registers are
909;       saved. If nonblank and identical to "Rbp", then rbp is saved in
910;       addition to the nonvolatile floating and integer registers. If
911;       nonblank and identical to "NoFp", then only the nonvolatile integer
912;       registers are saved. If nonblank and identical to "NoPop", then
913;       allocate an exception record in addition to an exception frame. If
914;       nonblank and identical to "NoFrame", then rbp is saved in addition to
915;       the other registers but is not established as a frame pointer.
916;
917; Implicit arguments:
918;
919;   The top of the stack is assumed to contain a return address.
920;
921
922GENERATE_EXCEPTION_FRAME macro Flag
923
924
925ifidn <Flag>, <NoPop>
926
927        alloc_stack (EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH - (1 * 8)) ; allocate frame
928
929else
930
931        alloc_stack (KEXCEPTION_FRAME_LENGTH - (1 * 8)) ; allocate frame
932
933endif
934
935        lea     rax, 100h[rsp]          ; set frame display pointer
936
937ifdif <Flag>, <NoFp>
938
939        save_xmm128 xmm6, ExXmm6        ; save xmm nonvolatile registers
940        save_xmm128 xmm7, ExXmm7        ;
941        save_xmm128 xmm8, ExXmm8        ;
942        save_xmm128 xmm9, ExXmm9        ;
943        save_xmm128 xmm10, ExXmm10      ;
944
945        movaps  (ExXmm11 - 100h)[rax], xmm11 ;
946        .savexmm128 xmm11, ExXmm11      ;
947
948        movaps  (ExXmm12 - 100h)[rax], xmm12 ;
949        .savexmm128 xmm12, ExXmm12      ;
950
951        movaps  (ExXmm13 - 100h)[rax], xmm13 ;
952        .savexmm128 xmm13, ExXmm13      ;
953
954        movaps  (ExXmm14 - 100h)[rax], xmm14 ;
955        .savexmm128 xmm14, ExXmm14      ;
956
957        movaps  (ExXmm15 - 100h)[rax], xmm15 ;
958        .savexmm128 xmm15, ExXmm15      ;
959
960endif
961
962ifidn <Flag>, <Rbp>
963
964        mov     (ExRbp - 100h)[rax], rbp  ; save nonvolatile integer register
965        .savereg rbp, ExRbp             ;
966        set_frame rbp, 0                ; set frame pointer
967
968endif
969
970ifidn <Flag>, <NoFrame>
971
972        mov     (ExRbp - 100h)[rax], rbp  ; save nonvolatile integer register
973        .savereg rbp, ExRbp             ;
974
975endif
976
977        mov     (ExRbx - 100h)[rax], rbx  ;
978        .savereg rbx, ExRbx             ;
979
980        mov     (ExRdi - 100h)[rax], rdi  ;
981        .savereg rdi, ExRdi             ;
982
983        mov     (ExRsi - 100h)[rax], rsi  ;
984        .savereg rsi, ExRsi             ;
985
986        mov     (ExR12 - 100h)[rax], r12  ;
987        .savereg r12, ExR12             ;
988
989        mov     (ExR13 - 100h)[rax], r13  ;
990        .savereg r13, ExR13             ;
991
992        mov     (ExR14 - 100h)[rax], r14  ;
993        .savereg r14, ExR14             ;
994
995        mov     (ExR15 - 100h)[rax], r15  ;
996        .savereg r15, ExR15             ;
997
998        END_PROLOGUE
999
1000        endm
1001
1002;
1003