VirtualBox

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

Last change on this file since 97613 was 97612, checked in by vboxsync, 2 years ago

ValKit/bs3kit: Comments. bugref:9898

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