VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm@ 84271

Last change on this file since 84271 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.0 KB
Line 
1; $Id: bs3-cmn-RegCtxRestore.asm 82968 2020-02-04 10:35:17Z vboxsync $
2;; @file
3; BS3Kit - Bs3RegCtxRestore.
4;
5
6;
7; Copyright (C) 2007-2020 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27%include "bs3kit-template-header.mac"
28
29
30BS3_EXTERN_SYSTEM16 Bs3Gdt
31BS3_EXTERN_DATA16 g_bBs3CurrentMode
32BS3_EXTERN_DATA16 g_fBs3TrapNoV86Assist
33%if TMPL_BITS != 64
34BS3_EXTERN_DATA16 g_uBs3CpuDetected
35%endif
36TMPL_BEGIN_TEXT
37BS3_EXTERN_CMN Bs3Syscall
38BS3_EXTERN_CMN Bs3Panic
39TMPL_BEGIN_TEXT
40
41
42;;
43; Restores the given register context.
44;
45; @param pRegCtx
46; @param fFlags
47; @uses All registers and may trash stack immediately before the resume point.
48;
49; @note Only respects the BS3_MODE_CODE_MASK part of pRegCtx->bMode.
50;
51%if TMPL_BITS == 16
52BS3_PROC_BEGIN_CMN Bs3RegCtxRestore_aborts, BS3_PBC_FAR ; special entry point for when watcom applies __aborts
53BS3_PROC_BEGIN_CMN Bs3RegCtxRestore_aborts, BS3_PBC_NEAR ; special entry point for when watcom applies __aborts
54 CPU 8086
55 xor xAX, xAX
56 push xAX ; fake return address.
57 push xAX
58 jmp _Bs3RegCtxRestore_f16
59%elif TMPL_BITS == 32
60BS3_PROC_BEGIN_CMN Bs3RegCtxRestore_aborts, BS3_PBC_NEAR ; special entry point for when watcom applies __aborts
61 push 0feedfaceh ; fake return address.
62%endif
63BS3_PROC_BEGIN_CMN Bs3RegCtxRestore, BS3_PBC_HYBRID
64 BS3_CALL_CONV_PROLOG 2
65 push xBP
66 mov xBP, xSP
67
68 ;
69 ; If we're not in ring-0, ask the kernel to restore it for us (quicker
70 ; and less problematic if we're in a funny context right now with weird
71 ; CS or SS values).
72 ;
73%if TMPL_BITS == 16
74 cmp byte [BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
75 je .in_ring0
76 test byte [BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_CODE_V86
77 jnz .do_syscall_restore_ctx
78%endif
79 mov ax, ss
80 test al, 3
81 jz .in_ring0
82
83.do_syscall_restore_ctx:
84%if TMPL_BITS != 16
85.do_syscall_restore_ctx_restore_ds:
86 mov cx, ds
87 mov xSI, [xBP + xCB*2]
88 movzx edx, word [xBP + xCB*3]
89 mov eax, BS3_SYSCALL_RESTORE_CTX
90%else
91 mov si, [bp + xCB + cbCurRetAddr]
92 mov cx, [bp + xCB + cbCurRetAddr + 2]
93 mov dx, [bp + xCB + cbCurRetAddr + sCB]
94 mov ax, BS3_SYSCALL_RESTORE_CTX
95%endif
96 call Bs3Syscall
97 call Bs3Panic
98
99%if TMPL_BITS == 16
100.do_syscall_restore_ctx_restore_ds:
101 push es
102 pop ds
103 jmp .do_syscall_restore_ctx
104%endif
105
106 ;
107 ; Prologue. Loads ES with BS3KIT_GRPNM_DATA16/FLAT (for g_bBs3CurrentMode
108 ; and g_uBs3CpuDetected), DS:xBX with pRegCtx and fFlags into xCX.
109 ;
110.in_ring0:
111%if TMPL_BITS == 16
112 mov ax, BS3_SEL_DATA16
113 mov es, ax
114 lds bx, [bp + xCB + cbCurRetAddr]
115 mov cx, [bp + xCB + cbCurRetAddr + sCB]
116%elif TMPL_BITS == 32
117 mov ax, BS3_SEL_R0_DS32
118 mov ds, ax
119 mov xBX, [xBP + xCB*2]
120 movzx xCX, word [xBP + xCB*3]
121%else
122 mov ax, BS3_SEL_R0_DS64
123 mov ds, ax
124 mov xBX, [xBP + xCB*2]
125 movzx xCX, word [xBP + xCB*3]
126%endif
127
128
129%if TMPL_BITS != 64
130 ; Restoring a 64-bit context is best done from 64-bit code.
131 mov al, [xBX + BS3REGCTX.bMode]
132 test al, BS3_MODE_CODE_64
133 jnz .do_syscall_restore_ctx_restore_ds
134%endif
135
136 ; The remainder must be done with interrupts disabled.
137 cli
138
139 ;
140 ; Update g_bs3CurrentMode.
141 ;
142%if TMPL_BITS == 64
143 mov al, [xBX + BS3REGCTX.bMode]
144%endif
145 and al, BS3_MODE_CODE_MASK
146 mov ah, [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)]
147 and ah, ~BS3_MODE_CODE_MASK
148 or al, ah
149 mov [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)], al
150
151 ;
152 ; Set g_fBs3TrapNoV86Assist if BS3REGCTXRESTORE_F_NO_V86_ASSIST specified.
153 ;
154 test cl, BS3REGCTXRESTORE_F_NO_V86_ASSIST
155 jz .no_f_no_v86_assist
156 mov byte [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_fBs3TrapNoV86Assist)], 1
157.no_f_no_v86_assist:
158
159%if TMPL_BITS == 16
160 ;
161 ; Check what the CPU can do.
162 ;
163 cmp byte [es:BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80386
164 jae .restore_full
165
166 ; Do the 80286 specifics first.
167 cmp byte [es:BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
168 jb .restore_16_bit_ancient
169 CPU 286
170
171 lmsw [bx + BS3REGCTX.cr0]
172 cmp byte [es:BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
173 je .restore_16_bit_ancient
174 lldt [bx + BS3REGCTX.ldtr]
175
176 ; TR - complicated because we need to clear the busy bit. ASSUMES GDT.
177 str ax
178 cmp ax, [bx + BS3REGCTX.tr]
179 je .skip_tr_286
180
181 mov di, word [xBX + BS3REGCTX.tr]
182 or di, di ; check for null.
183 jz .load_tr_286
184
185 push ds
186 push BS3_SEL_SYSTEM16
187 pop ds
188 add di, Bs3Gdt wrt BS3SYSTEM16
189 add di, X86DESCGENERIC_BIT_OFF_TYPE / 8
190 and byte [di], ~(X86_SEL_TYPE_SYS_TSS_BUSY_MASK << (X86DESCGENERIC_BIT_OFF_TYPE % 8))
191 pop ds
192
193.load_tr_286:
194 ltr [bx + BS3REGCTX.tr]
195.skip_tr_286:
196
197.restore_16_bit_ancient:
198 CPU 8086
199 ; Some general registers.
200 mov cx, [bx + BS3REGCTX.rcx]
201 mov dx, [bx + BS3REGCTX.rdx]
202
203 ; Do the return frame and final registers (keep short as we're not quite
204 ; NMI safe here if pRegCtx is on the stack).
205 cmp byte [es:BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
206 mov di, [bx + BS3REGCTX.rsp]
207 je .restore_16_bit_same_privilege
208 cmp byte [bx + BS3REGCTX.bCpl], 0
209 je .restore_16_bit_same_privilege
210
211 mov ax, [bx + BS3REGCTX.ss]
212 push ax
213 mov ax, [bx + BS3REGCTX.rsp]
214 push ax
215 mov ax, [bx + BS3REGCTX.rflags]
216 push ax
217 mov ax, [bx + BS3REGCTX.cs]
218 push ax
219 mov ax, [bx + BS3REGCTX.rip]
220 push ax
221 mov ax, [bx + BS3REGCTX.ds]
222 push ax
223
224 mov si, [bx + BS3REGCTX.rsi]
225 mov di, [bx + BS3REGCTX.rdi]
226 mov es, [bx + BS3REGCTX.es]
227 mov ax, [bx + BS3REGCTX.rax]
228 mov bp, [bx + BS3REGCTX.rbp] ; restore late for better stacks.
229 mov bx, [bx + BS3REGCTX.rbx]
230
231 pop ds
232 iret
233
234.restore_16_bit_same_privilege:
235 sub di, 2*5 ; iret frame + pop ds
236 mov si, di
237 mov es, [bx + BS3REGCTX.ss] ; ES is target stack segment.
238 cld
239
240 mov ax, [bx + BS3REGCTX.ds]
241 stosw
242 mov ax, [bx + BS3REGCTX.rbp] ; Restore esp as late as possible for better stacks.
243 stosw
244 mov ax, [bx + BS3REGCTX.rip]
245 stosw
246 mov ax, [bx + BS3REGCTX.cs]
247 stosw
248 mov ax, [bx + BS3REGCTX.rflags]
249 stosw
250
251 mov di, [bx + BS3REGCTX.rdi]
252 mov es, [bx + BS3REGCTX.es]
253 mov ax, [bx + BS3REGCTX.rax]
254 mov ss, [bx + BS3REGCTX.ss]
255 mov sp, si
256 mov si, [bx + BS3REGCTX.rsi]
257 mov bx, [bx + BS3REGCTX.rbx]
258
259 pop ds
260 pop bp
261 iret
262
263 CPU 386
264%endif
265
266.restore_full:
267 ;
268 ; 80386 or later.
269 ; For 32-bit and 16-bit versions, we always use 32-bit iret.
270 ;
271
272 ; Restore control registers if they've changed.
273 test cl, BS3REGCTXRESTORE_F_SKIP_CRX
274 jnz .skip_control_regs
275 test byte [xBX + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR0_IS_MSW | BS3REG_CTX_F_NO_CR2_CR3
276 jnz .skip_control_regs
277
278 test byte [xBX + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4 ; (old 486s and 386s didn't have CR4)
279 jnz .skip_cr4
280%if TMPL_BITS != 64
281 test word [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_F_CPUID
282 jz .skip_cr4
283%endif
284 mov sAX, [xBX + BS3REGCTX.cr4]
285 mov sDX, cr4
286 cmp sAX, sDX
287 je .skip_cr4
288 mov cr4, sAX
289.skip_cr4:
290
291 mov sAX, [xBX + BS3REGCTX.cr0]
292 mov sDX, cr0
293 cmp sAX, sDX
294 je .skip_cr0
295 mov cr0, sAX
296.skip_cr0:
297
298 mov sAX, [xBX + BS3REGCTX.cr3]
299 mov sDX, cr3
300 cmp sAX, sDX
301 je .skip_cr3
302 mov cr3, sAX
303.skip_cr3:
304
305 mov sAX, [xBX + BS3REGCTX.cr2]
306 mov sDX, cr2
307 cmp sAX, sDX
308 je .skip_cr2
309 mov cr2, sAX
310.skip_cr2:
311
312 ;
313 ; Restore
314 ;
315%if TMPL_BITS != 64
316 ; We cannot restore ldtr and tr if we're in real-mode.
317 cmp byte [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
318 je .skip_control_regs
319%endif
320 test byte [xBX + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_TR_LDTR
321 jnz .skip_control_regs
322
323 ; LDTR
324 sldt ax
325 cmp ax, [xBX + BS3REGCTX.ldtr]
326 je .skip_ldtr
327 lldt [xBX + BS3REGCTX.ldtr]
328.skip_ldtr:
329
330 ; TR - complicated because we need to clear the busy bit. ASSUMES GDT.
331 str ax
332 cmp ax, [xBX + BS3REGCTX.tr]
333 je .skip_tr
334
335 movzx edi, word [xBX + BS3REGCTX.tr]
336 or edi, edi ; check for null.
337 jz .load_tr
338
339%if TMPL_BITS == 16
340 push ds
341 push BS3_SEL_SYSTEM16
342 pop ds
343 add xDI, Bs3Gdt wrt BS3SYSTEM16
344%else
345 add xDI, Bs3Gdt wrt FLAT
346%endif
347 add xDI, X86DESCGENERIC_BIT_OFF_TYPE / 8
348 and byte [xDI], ~(X86_SEL_TYPE_SYS_TSS_BUSY_MASK << (X86DESCGENERIC_BIT_OFF_TYPE % 8))
349%if TMPL_BITS == 16
350 pop ds
351%endif
352.load_tr:
353 ltr [xBX + BS3REGCTX.tr]
354.skip_tr:
355
356.skip_control_regs:
357
358
359%if TMPL_BITS == 64
360 ;
361 ; 64-bit returns are simple because ss:rsp are always restored.
362 ;
363 ; A small complication here when returning to a 16-bit stack (only
364 ; applicable to 16-bit and 32-bit code), iret doesn't touch the high
365 ; ESP bits and we can easily later end up with trap handlers
366 ; accessing memory never intended as stack.
367 ;
368 mov rcx, qword [xBX + BS3REGCTX.rsp] ; (also 1st param for conv call below)
369 cmp rcx, 0ffffh
370 ja .iretq_maybe_annoying_16bit_stack
371 cmp rsp, 0ffffh
372 ja .iretq_maybe_annoying_16bit_stack
373.iretq_ok:
374
375 movzx eax, word [xBX + BS3REGCTX.ss]
376 push rax
377 push qword [xBX + BS3REGCTX.rsp]
378 push qword [xBX + BS3REGCTX.rflags]
379 movzx eax, word [xBX + BS3REGCTX.cs]
380 push rax
381 push qword [xBX + BS3REGCTX.rip]
382
383.iretq_restore_regs_and_iret:
384 mov es, [xBX + BS3REGCTX.es]
385 mov fs, [xBX + BS3REGCTX.fs]
386 mov gs, [xBX + BS3REGCTX.gs]
387 mov rax, [xBX + BS3REGCTX.rax]
388 mov rdx, [xBX + BS3REGCTX.rdx]
389 mov rcx, [xBX + BS3REGCTX.rcx]
390 mov rsi, [xBX + BS3REGCTX.rsi]
391 mov rdi, [xBX + BS3REGCTX.rdi]
392 mov r8, [xBX + BS3REGCTX.r8]
393 mov r9, [xBX + BS3REGCTX.r9]
394 mov r10, [xBX + BS3REGCTX.r10]
395 mov r11, [xBX + BS3REGCTX.r11]
396 mov r12, [xBX + BS3REGCTX.r12]
397 mov r13, [xBX + BS3REGCTX.r13]
398 mov r14, [xBX + BS3REGCTX.r14]
399 mov r15, [xBX + BS3REGCTX.r15]
400 mov rbp, [xBX + BS3REGCTX.rbp] ; restore late for better stacks.
401 mov ds, [xBX + BS3REGCTX.ds]
402 mov rbx, [xBX + BS3REGCTX.rbx]
403 iretq
404
405.iretq_maybe_annoying_16bit_stack:
406 movzx edx, word [xBX + BS3REGCTX.ss] ; (also 2nd param for conv call below)
407 lar eax, dx
408 jnz .iretq_ok
409 test eax, X86LAR_F_D | X86LAR_F_L
410 jnz .iretq_ok ; Returning to a big of long SS needs not extra work.
411
412 lar eax, word [xBX + BS3REGCTX.cs]
413 jnz .iretq_ok
414 test eax, X86LAR_F_L
415 jnz .iretq_ok ; It doesn't matter when returning to 64-bit code.
416
417 ; Convert ss:sp to a flat address.
418 BS3_EXTERN_CMN Bs3SelFar32ToFlat32NoClobber
419 call Bs3SelFar32ToFlat32NoClobber
420 mov rdi, rax
421
422 ; 2nd return frame (32-bit, same CPL).
423 mov eax, [xBX + BS3REGCTX.rflags]
424 mov [rdi - 4], eax
425 movzx eax, word [xBX + BS3REGCTX.cs]
426 mov [rdi - 8], eax
427 mov eax, [xBX + BS3REGCTX.rip]
428 mov [rdi - 12], eax
429 mov ecx, [xBX + BS3REGCTX.rsp]
430 sub cx, 12
431 mov [rdi - 16], ecx
432
433 ; 1st return frame.
434 movzx eax, word [xBX + BS3REGCTX.ss]
435 push rax ; new 16-bit SS
436 sub cx, 4
437 push rcx ; new esp
438 mov rax, [xBX + BS3REGCTX.rflags]
439 and rax, ~(X86_EFL_NT | X86_EFL_TF)
440 push rax ; rflags
441 AssertCompile(BS3_SEL_RING_SHIFT == 8)
442 mov eax, BS3_SEL_R0_CS32
443 add ah, [xBX + BS3REGCTX.bCpl]
444 or al, [xBX + BS3REGCTX.bCpl]
445 push rax ; 32-bit CS
446 push .iretq_pop_real_esp_and_iret_again wrt FLAT
447 jmp .iretq_restore_regs_and_iret
448
449 BS3_SET_BITS 32
450.iretq_pop_real_esp_and_iret_again:
451 pop esp
452 iretd
453 BS3_SET_BITS 64
454
455%else
456 ;
457 ; 32-bit/16-bit is more complicated as we have three different iret frames.
458 ;
459 mov al, [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)]
460 cmp al, BS3_MODE_RM
461 je .iretd_same_cpl_rm
462
463 test dword [xBX + BS3REGCTX.rflags], X86_EFL_VM
464 jnz .restore_v8086
465
466 cmp byte [xBX + BS3REGCTX.bCpl], 0
467 je .iretd_same_cpl
468
469 ;
470 ; IRETD to different CPL. Frame includes ss:esp.
471 ;
472.iretd_different_cpl:
473 or eax, 0ffffffffh ; poison unused parts of segment pushes
474 mov ax, [xBX + BS3REGCTX.ss]
475 push eax
476 push dword [xBX + BS3REGCTX.rsp]
477 push dword [xBX + BS3REGCTX.rflags]
478 mov ax, [xBX + BS3REGCTX.cs]
479 push eax
480 push dword [xBX + BS3REGCTX.rip]
481 push dword [xBX + BS3REGCTX.rbp] ; Restore esp as late as possible for better stacks.
482 mov ax, [xBX + BS3REGCTX.ds]
483 push xAX
484
485 mov es, [xBX + BS3REGCTX.es]
486 mov fs, [xBX + BS3REGCTX.fs]
487 mov gs, [xBX + BS3REGCTX.gs]
488 mov eax, [xBX + BS3REGCTX.rax]
489 mov edx, [xBX + BS3REGCTX.rdx]
490 mov ecx, [xBX + BS3REGCTX.rcx]
491 mov esi, [xBX + BS3REGCTX.rsi]
492 %if TMPL_BITS == 16 ; if SS is 16-bit, we will not be able to restore the high word.
493;; @todo 16-bit stack will also mess us up in 32-bit code, so this needs fixing (see 64-bit above).
494 mov edi, [xBX + BS3REGCTX.rsp]
495 mov di, sp
496 mov esp, edi
497 %endif
498 mov edi, [xBX + BS3REGCTX.rdi]
499 mov ebx, [xBX + BS3REGCTX.rbx]
500
501 pop ds
502 pop ebp
503 iretd
504
505 ;
506 ; IRETD to same CPL (includes real mode).
507 ;
508.iretd_same_cpl_rm:
509 ; Use STOSD/ES:EDI to create the frame.
510 mov es, [xBX + BS3REGCTX.ss]
511 mov esi, [xBX + BS3REGCTX.rsp]
512 sub esi, 5*4
513 movzx edi, si
514 jmp .es_edi_is_pointing_to_return_frame_location
515
516.iretd_same_cpl:
517 ; Use STOSD/ES:EDI to create the frame.
518 mov es, [xBX + BS3REGCTX.ss]
519 mov edi, [xBX + BS3REGCTX.rsp]
520 sub edi, 5*4
521
522 ; Which part of the stack pointer is actually used depends on the SS.D/B bit.
523 lar eax, [xBX + BS3REGCTX.ss]
524 jnz .using_32_bit_stack_pointer
525 test eax, X86LAR_F_D
526 jnz .using_32_bit_stack_pointer
527.using_16_bit_stack_pointer:
528 mov esi, edi ; save rsp for later.
529 movzx edi, di
530 jmp .es_edi_is_pointing_to_return_frame_location
531.using_32_bit_stack_pointer:
532 mov esi, edi
533.es_edi_is_pointing_to_return_frame_location:
534 cld
535 mov ax, [xBX + BS3REGCTX.ds]
536 o32 stosd
537 mov eax, [xBX + BS3REGCTX.rbp] ; Restore esp as late as possible for better stacks.
538 o32 stosd
539 mov eax, [xBX + BS3REGCTX.rip]
540 o32 stosd
541 mov ax, [xBX + BS3REGCTX.cs]
542 o32 stosd
543 mov eax, [xBX + BS3REGCTX.rflags]
544 o32 stosd
545
546 mov es, [xBX + BS3REGCTX.es]
547 mov fs, [xBX + BS3REGCTX.fs]
548 mov gs, [xBX + BS3REGCTX.gs]
549 mov eax, [xBX + BS3REGCTX.rax]
550 mov edx, [xBX + BS3REGCTX.rdx]
551 mov ecx, [xBX + BS3REGCTX.rcx]
552 mov edi, [xBX + BS3REGCTX.rdi]
553 mov ebp, [xBX + BS3REGCTX.rbp] ; restore late for better stacks.
554
555 mov ss, [xBX + BS3REGCTX.ss]
556 mov esp, esi
557 mov esi, [xBX + BS3REGCTX.rsi]
558 mov ebx, [xBX + BS3REGCTX.rbx]
559
560 o32 pop ds
561 pop ebp
562 iretd
563
564 ;
565 ; IRETD to v8086 mode. Frame includes ss:esp and the 4 data segment registers.
566 ;
567.restore_v8086:
568 or eax, 0ffffffffh ; poison unused parts of segment pushes
569 mov eax, [xBX + BS3REGCTX.gs]
570 push eax
571 mov eax, [xBX + BS3REGCTX.fs]
572 push eax
573 mov eax, [xBX + BS3REGCTX.ds]
574 push eax
575 mov eax, [xBX + BS3REGCTX.es]
576 push eax
577 mov eax, [xBX + BS3REGCTX.ss]
578 push eax
579 push dword [xBX + BS3REGCTX.rsp]
580 push dword [xBX + BS3REGCTX.rflags]
581 mov ax, [xBX + BS3REGCTX.cs]
582 push eax
583 push dword [xBX + BS3REGCTX.rip]
584
585 mov eax, [xBX + BS3REGCTX.rax]
586 mov edx, [xBX + BS3REGCTX.rdx]
587 mov ecx, [xBX + BS3REGCTX.rcx]
588 mov esi, [xBX + BS3REGCTX.rsi]
589 mov edi, [xBX + BS3REGCTX.rdi]
590 mov ebp, [xBX + BS3REGCTX.rbp] ; restore late for better stacks.
591 mov ebx, [xBX + BS3REGCTX.rbx]
592
593 iretd
594%endif
595BS3_PROC_END_CMN Bs3RegCtxRestore
596
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette