]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm
UefiCpuPkg: Add PiSmmCpuDxeSmm module IA32 files
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiException.asm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
3 ; This program and the accompanying materials
4 ; are licensed and made available under the terms and conditions of the BSD License
5 ; which accompanies this distribution. The full text of the license may be found at
6 ; http://opensource.org/licenses/bsd-license.php.
7 ;
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 ;
11 ; Module Name:
12 ;
13 ; SmiException.asm
14 ;
15 ; Abstract:
16 ;
17 ; Exception handlers used in SM mode
18 ;
19 ;-------------------------------------------------------------------------------
20
21 .686p
22 .model flat,C
23
24 EXTERNDEF SmiPFHandler:PROC
25 EXTERNDEF PageFaultStubFunction:PROC
26 EXTERNDEF gSmiMtrrs:QWORD
27 EXTERNDEF gcSmiIdtr:FWORD
28 EXTERNDEF gcSmiGdtr:FWORD
29 EXTERNDEF gcPsd:BYTE
30 EXTERNDEF FeaturePcdGet (PcdCpuSmmProfileEnable):BYTE
31
32
33 .data
34
35 NullSeg DQ 0 ; reserved by architecture
36 CodeSeg32 LABEL QWORD
37 DW -1 ; LimitLow
38 DW 0 ; BaseLow
39 DB 0 ; BaseMid
40 DB 9bh
41 DB 0cfh ; LimitHigh
42 DB 0 ; BaseHigh
43 ProtModeCodeSeg32 LABEL QWORD
44 DW -1 ; LimitLow
45 DW 0 ; BaseLow
46 DB 0 ; BaseMid
47 DB 9bh
48 DB 0cfh ; LimitHigh
49 DB 0 ; BaseHigh
50 ProtModeSsSeg32 LABEL QWORD
51 DW -1 ; LimitLow
52 DW 0 ; BaseLow
53 DB 0 ; BaseMid
54 DB 93h
55 DB 0cfh ; LimitHigh
56 DB 0 ; BaseHigh
57 DataSeg32 LABEL QWORD
58 DW -1 ; LimitLow
59 DW 0 ; BaseLow
60 DB 0 ; BaseMid
61 DB 93h
62 DB 0cfh ; LimitHigh
63 DB 0 ; BaseHigh
64 CodeSeg16 LABEL QWORD
65 DW -1
66 DW 0
67 DB 0
68 DB 9bh
69 DB 8fh
70 DB 0
71 DataSeg16 LABEL QWORD
72 DW -1
73 DW 0
74 DB 0
75 DB 93h
76 DB 8fh
77 DB 0
78 CodeSeg64 LABEL QWORD
79 DW -1 ; LimitLow
80 DW 0 ; BaseLow
81 DB 0 ; BaseMid
82 DB 9bh
83 DB 0afh ; LimitHigh
84 DB 0 ; BaseHigh
85 GDT_SIZE = $ - offset NullSeg
86
87 TssSeg LABEL QWORD
88 DW TSS_DESC_SIZE ; LimitLow
89 DW 0 ; BaseLow
90 DB 0 ; BaseMid
91 DB 89h
92 DB 080h ; LimitHigh
93 DB 0 ; BaseHigh
94 ExceptionTssSeg LABEL QWORD
95 DW TSS_DESC_SIZE ; LimitLow
96 DW 0 ; BaseLow
97 DB 0 ; BaseMid
98 DB 89h
99 DB 080h ; LimitHigh
100 DB 0 ; BaseHigh
101
102 CODE_SEL = offset CodeSeg32 - offset NullSeg
103 DATA_SEL = offset DataSeg32 - offset NullSeg
104 TSS_SEL = offset TssSeg - offset NullSeg
105 EXCEPTION_TSS_SEL = offset ExceptionTssSeg - offset NullSeg
106
107 IA32_TSS STRUC
108 DW ?
109 DW ?
110 ESP0 DD ?
111 SS0 DW ?
112 DW ?
113 ESP1 DD ?
114 SS1 DW ?
115 DW ?
116 ESP2 DD ?
117 SS2 DW ?
118 DW ?
119 _CR3 DD ?
120 EIP DD ?
121 EFLAGS DD ?
122 _EAX DD ?
123 _ECX DD ?
124 _EDX DD ?
125 _EBX DD ?
126 _ESP DD ?
127 _EBP DD ?
128 _ESI DD ?
129 _EDI DD ?
130 _ES DW ?
131 DW ?
132 _CS DW ?
133 DW ?
134 _SS DW ?
135 DW ?
136 _DS DW ?
137 DW ?
138 _FS DW ?
139 DW ?
140 _GS DW ?
141 DW ?
142 LDT DW ?
143 DW ?
144 DW ?
145 DW ?
146 IA32_TSS ENDS
147
148 ; Create 2 TSS segments just after GDT
149 TssDescriptor LABEL BYTE
150 DW 0 ; PreviousTaskLink
151 DW 0 ; Reserved
152 DD 0 ; ESP0
153 DW 0 ; SS0
154 DW 0 ; Reserved
155 DD 0 ; ESP1
156 DW 0 ; SS1
157 DW 0 ; Reserved
158 DD 0 ; ESP2
159 DW 0 ; SS2
160 DW 0 ; Reserved
161 DD 0 ; CR3
162 DD 0 ; EIP
163 DD 0 ; EFLAGS
164 DD 0 ; EAX
165 DD 0 ; ECX
166 DD 0 ; EDX
167 DD 0 ; EBX
168 DD 0 ; ESP
169 DD 0 ; EBP
170 DD 0 ; ESI
171 DD 0 ; EDI
172 DW 0 ; ES
173 DW 0 ; Reserved
174 DW 0 ; CS
175 DW 0 ; Reserved
176 DW 0 ; SS
177 DW 0 ; Reserved
178 DW 0 ; DS
179 DW 0 ; Reserved
180 DW 0 ; FS
181 DW 0 ; Reserved
182 DW 0 ; GS
183 DW 0 ; Reserved
184 DW 0 ; LDT Selector
185 DW 0 ; Reserved
186 DW 0 ; T
187 DW 0 ; I/O Map Base
188 TSS_DESC_SIZE = $ - offset TssDescriptor
189
190 ExceptionTssDescriptor LABEL BYTE
191 DW 0 ; PreviousTaskLink
192 DW 0 ; Reserved
193 DD 0 ; ESP0
194 DW 0 ; SS0
195 DW 0 ; Reserved
196 DD 0 ; ESP1
197 DW 0 ; SS1
198 DW 0 ; Reserved
199 DD 0 ; ESP2
200 DW 0 ; SS2
201 DW 0 ; Reserved
202 DD 0 ; CR3
203 DD offset PFHandlerEntry ; EIP
204 DD 00000002 ; EFLAGS
205 DD 0 ; EAX
206 DD 0 ; ECX
207 DD 0 ; EDX
208 DD 0 ; EBX
209 DD 0 ; ESP
210 DD 0 ; EBP
211 DD 0 ; ESI
212 DD 0 ; EDI
213 DW DATA_SEL ; ES
214 DW 0 ; Reserved
215 DW CODE_SEL ; CS
216 DW 0 ; Reserved
217 DW DATA_SEL ; SS
218 DW 0 ; Reserved
219 DW DATA_SEL ; DS
220 DW 0 ; Reserved
221 DW DATA_SEL ; FS
222 DW 0 ; Reserved
223 DW DATA_SEL ; GS
224 DW 0 ; Reserved
225 DW 0 ; LDT Selector
226 DW 0 ; Reserved
227 DW 0 ; T
228 DW 0 ; I/O Map Base
229
230 gcPsd LABEL BYTE
231 DB 'PSDSIG '
232 DW PSD_SIZE
233 DW 2
234 DW 1 SHL 2
235 DW CODE_SEL
236 DW DATA_SEL
237 DW DATA_SEL
238 DW DATA_SEL
239 DW 0
240 DQ 0
241 DQ 0
242 DQ 0
243 DQ offset NullSeg
244 DD GDT_SIZE
245 DD 0
246 DB 24 dup (0)
247 DQ offset gSmiMtrrs
248 PSD_SIZE = $ - offset gcPsd
249
250 gcSmiGdtr LABEL FWORD
251 DW GDT_SIZE - 1
252 DD offset NullSeg
253
254 gcSmiIdtr LABEL FWORD
255 DW IDT_SIZE - 1
256 DD offset _SmiIDT
257
258 _SmiIDT LABEL QWORD
259 REPEAT 32
260 DW 0 ; Offset 0:15
261 DW CODE_SEL ; Segment selector
262 DB 0 ; Unused
263 DB 8eh ; Interrupt Gate, Present
264 DW 0 ; Offset 16:31
265 ENDM
266 IDT_SIZE = $ - offset _SmiIDT
267
268 TaskGateDescriptor LABEL DWORD
269 DW 0 ; Reserved
270 DW EXCEPTION_TSS_SEL ; TSS Segment selector
271 DB 0 ; Reserved
272 DB 85h ; Task Gate, present, DPL = 0
273 DW 0 ; Reserved
274
275
276 .code
277 ;------------------------------------------------------------------------------
278 ; PageFaultIdtHandlerSmmProfile is the entry point page fault only
279 ;
280 ;
281 ; Stack:
282 ; +---------------------+
283 ; + EFlags +
284 ; +---------------------+
285 ; + CS +
286 ; +---------------------+
287 ; + EIP +
288 ; +---------------------+
289 ; + Error Code +
290 ; +---------------------+
291 ; + Vector Number +
292 ; +---------------------+
293 ; + EBP +
294 ; +---------------------+ <-- EBP
295 ;
296 ;
297 ;------------------------------------------------------------------------------
298 PageFaultIdtHandlerSmmProfile PROC
299 push 0eh ; Page Fault
300
301 push ebp
302 mov ebp, esp
303
304
305 ;
306 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
307 ; is 16-byte aligned
308 ;
309 and esp, 0fffffff0h
310 sub esp, 12
311
312 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
313 push eax
314 push ecx
315 push edx
316 push ebx
317 lea ecx, [ebp + 6 * 4]
318 push ecx ; ESP
319 push dword ptr [ebp] ; EBP
320 push esi
321 push edi
322
323 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
324 mov eax, ss
325 push eax
326 movzx eax, word ptr [ebp + 4 * 4]
327 push eax
328 mov eax, ds
329 push eax
330 mov eax, es
331 push eax
332 mov eax, fs
333 push eax
334 mov eax, gs
335 push eax
336
337 ;; UINT32 Eip;
338 mov eax, [ebp + 3 * 4]
339 push eax
340
341 ;; UINT32 Gdtr[2], Idtr[2];
342 sub esp, 8
343 sidt [esp]
344 mov eax, [esp + 2]
345 xchg eax, [esp]
346 and eax, 0FFFFh
347 mov [esp+4], eax
348
349 sub esp, 8
350 sgdt [esp]
351 mov eax, [esp + 2]
352 xchg eax, [esp]
353 and eax, 0FFFFh
354 mov [esp+4], eax
355
356 ;; UINT32 Ldtr, Tr;
357 xor eax, eax
358 str ax
359 push eax
360 sldt ax
361 push eax
362
363 ;; UINT32 EFlags;
364 mov eax, [ebp + 5 * 4]
365 push eax
366
367 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
368 mov eax, cr4
369 or eax, 208h
370 mov cr4, eax
371 push eax
372 mov eax, cr3
373 push eax
374 mov eax, cr2
375 push eax
376 xor eax, eax
377 push eax
378 mov eax, cr0
379 push eax
380
381 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
382 mov eax, dr7
383 push eax
384 mov eax, dr6
385 push eax
386 mov eax, dr3
387 push eax
388 mov eax, dr2
389 push eax
390 mov eax, dr1
391 push eax
392 mov eax, dr0
393 push eax
394
395 ;; FX_SAVE_STATE_IA32 FxSaveState;
396 sub esp, 512
397 mov edi, esp
398 db 0fh, 0aeh, 07h ;fxsave [edi]
399
400 ; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
401 cld
402
403 ;; UINT32 ExceptionData;
404 push dword ptr [ebp + 2 * 4]
405
406 ;; call into exception handler
407
408 ;; Prepare parameter and call
409 mov edx, esp
410 push edx
411 mov edx, dword ptr [ebp + 1 * 4]
412 push edx
413
414 ;
415 ; Call External Exception Handler
416 ;
417 mov eax, SmiPFHandler
418 call eax
419 add esp, 8
420
421 ;; UINT32 ExceptionData;
422 add esp, 4
423
424 ;; FX_SAVE_STATE_IA32 FxSaveState;
425 mov esi, esp
426 db 0fh, 0aeh, 0eh ; fxrstor [esi]
427 add esp, 512
428
429 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
430 ;; Skip restoration of DRx registers to support debuggers
431 ;; that set breakpoint in interrupt/exception context
432 add esp, 4 * 6
433
434 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
435 pop eax
436 mov cr0, eax
437 add esp, 4 ; not for Cr1
438 pop eax
439 mov cr2, eax
440 pop eax
441 mov cr3, eax
442 pop eax
443 mov cr4, eax
444
445 ;; UINT32 EFlags;
446 pop dword ptr [ebp + 5 * 4]
447
448 ;; UINT32 Ldtr, Tr;
449 ;; UINT32 Gdtr[2], Idtr[2];
450 ;; Best not let anyone mess with these particular registers...
451 add esp, 24
452
453 ;; UINT32 Eip;
454 pop dword ptr [ebp + 3 * 4]
455
456 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
457 ;; NOTE - modified segment registers could hang the debugger... We
458 ;; could attempt to insulate ourselves against this possibility,
459 ;; but that poses risks as well.
460 ;;
461 pop gs
462 pop fs
463 pop es
464 pop ds
465 pop dword ptr [ebp + 4 * 4]
466 pop ss
467
468 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
469 pop edi
470 pop esi
471 add esp, 4 ; not for ebp
472 add esp, 4 ; not for esp
473 pop ebx
474 pop edx
475 pop ecx
476 pop eax
477
478 mov esp, ebp
479 pop ebp
480
481 ; Enable TF bit after page fault handler runs
482 bts dword ptr [esp + 16], 8 ; EFLAGS
483
484 add esp, 8 ; skip INT# & ErrCode
485 Return:
486 iretd
487 ;
488 ; Page Fault Exception Handler entry when SMM Stack Guard is enabled
489 ; Executiot starts here after a task switch
490 ;
491 PFHandlerEntry::
492 ;
493 ; Get this processor's TSS
494 ;
495 sub esp, 8
496 sgdt [esp + 2]
497 mov eax, [esp + 4] ; GDT base
498 add esp, 8
499 mov ecx, [eax + TSS_SEL + 2]
500 shl ecx, 8
501 mov cl, [eax + TSS_SEL + 7]
502 ror ecx, 8 ; ecx = TSS base
503
504 mov ebp, esp
505
506 ;
507 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
508 ; is 16-byte aligned
509 ;
510 and esp, 0fffffff0h
511 sub esp, 12
512
513 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
514 push (IA32_TSS ptr [ecx])._EAX
515 push (IA32_TSS ptr [ecx])._ECX
516 push (IA32_TSS ptr [ecx])._EDX
517 push (IA32_TSS ptr [ecx])._EBX
518 push (IA32_TSS ptr [ecx])._ESP
519 push (IA32_TSS ptr [ecx])._EBP
520 push (IA32_TSS ptr [ecx])._ESI
521 push (IA32_TSS ptr [ecx])._EDI
522
523 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
524 movzx eax, (IA32_TSS ptr [ecx])._SS
525 push eax
526 movzx eax, (IA32_TSS ptr [ecx])._CS
527 push eax
528 movzx eax, (IA32_TSS ptr [ecx])._DS
529 push eax
530 movzx eax, (IA32_TSS ptr [ecx])._ES
531 push eax
532 movzx eax, (IA32_TSS ptr [ecx])._FS
533 push eax
534 movzx eax, (IA32_TSS ptr [ecx])._GS
535 push eax
536
537 ;; UINT32 Eip;
538 push (IA32_TSS ptr [ecx]).EIP
539
540 ;; UINT32 Gdtr[2], Idtr[2];
541 sub esp, 8
542 sidt [esp]
543 mov eax, [esp + 2]
544 xchg eax, [esp]
545 and eax, 0FFFFh
546 mov [esp+4], eax
547
548 sub esp, 8
549 sgdt [esp]
550 mov eax, [esp + 2]
551 xchg eax, [esp]
552 and eax, 0FFFFh
553 mov [esp+4], eax
554
555 ;; UINT32 Ldtr, Tr;
556 mov eax, TSS_SEL
557 push eax
558 movzx eax, (IA32_TSS ptr [ecx]).LDT
559 push eax
560
561 ;; UINT32 EFlags;
562 push (IA32_TSS ptr [ecx]).EFLAGS
563
564 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
565 mov eax, cr4
566 or eax, 208h
567 mov cr4, eax
568 push eax
569 mov eax, cr3
570 push eax
571 mov eax, cr2
572 push eax
573 xor eax, eax
574 push eax
575 mov eax, cr0
576 push eax
577
578 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
579 mov eax, dr7
580 push eax
581 mov eax, dr6
582 push eax
583 mov eax, dr3
584 push eax
585 mov eax, dr2
586 push eax
587 mov eax, dr1
588 push eax
589 mov eax, dr0
590 push eax
591
592 ;; FX_SAVE_STATE_IA32 FxSaveState;
593 ;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)
594 ;; when executing fxsave/fxrstor instruction
595 clts
596 sub esp, 512
597 mov edi, esp
598 db 0fh, 0aeh, 07h ;fxsave [edi]
599
600 ; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
601 cld
602
603 ;; UINT32 ExceptionData;
604 push dword ptr [ebp]
605
606 ;; call into exception handler
607 mov ebx, ecx
608 mov eax, SmiPFHandler
609
610 ;; Prepare parameter and call
611 mov edx, esp
612 push edx
613 mov edx, 14
614 push edx
615
616 ;
617 ; Call External Exception Handler
618 ;
619 call eax
620 add esp, 8
621
622 mov ecx, ebx
623 ;; UINT32 ExceptionData;
624 add esp, 4
625
626 ;; FX_SAVE_STATE_IA32 FxSaveState;
627 mov esi, esp
628 db 0fh, 0aeh, 0eh ; fxrstor [esi]
629 add esp, 512
630
631 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
632 ;; Skip restoration of DRx registers to support debuggers
633 ;; that set breakpoints in interrupt/exception context
634 add esp, 4 * 6
635
636 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
637 pop eax
638 mov cr0, eax
639 add esp, 4 ; not for Cr1
640 pop eax
641 mov cr2, eax
642 pop eax
643 mov (IA32_TSS ptr [ecx])._CR3, eax
644 pop eax
645 mov cr4, eax
646
647 ;; UINT32 EFlags;
648 pop (IA32_TSS ptr [ecx]).EFLAGS
649
650 ;; UINT32 Ldtr, Tr;
651 ;; UINT32 Gdtr[2], Idtr[2];
652 ;; Best not let anyone mess with these particular registers...
653 add esp, 24
654
655 ;; UINT32 Eip;
656 pop (IA32_TSS ptr [ecx]).EIP
657
658 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
659 ;; NOTE - modified segment registers could hang the debugger... We
660 ;; could attempt to insulate ourselves against this possibility,
661 ;; but that poses risks as well.
662 ;;
663 pop eax
664 mov (IA32_TSS ptr [ecx])._GS, ax
665 pop eax
666 mov (IA32_TSS ptr [ecx])._FS, ax
667 pop eax
668 mov (IA32_TSS ptr [ecx])._ES, ax
669 pop eax
670 mov (IA32_TSS ptr [ecx])._DS, ax
671 pop eax
672 mov (IA32_TSS ptr [ecx])._CS, ax
673 pop eax
674 mov (IA32_TSS ptr [ecx])._SS, ax
675
676 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
677 pop (IA32_TSS ptr [ecx])._EDI
678 pop (IA32_TSS ptr [ecx])._ESI
679 add esp, 4 ; not for ebp
680 add esp, 4 ; not for esp
681 pop (IA32_TSS ptr [ecx])._EBX
682 pop (IA32_TSS ptr [ecx])._EDX
683 pop (IA32_TSS ptr [ecx])._ECX
684 pop (IA32_TSS ptr [ecx])._EAX
685
686 mov esp, ebp
687
688 ; Set single step DB# if SMM profile is enabled and page fault exception happens
689 cmp FeaturePcdGet (PcdCpuSmmProfileEnable), 0
690 jz @Done2
691
692 ; Create return context for iretd in stub function
693 mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer
694 mov ebx, (IA32_TSS ptr [ecx]).EIP
695 mov [eax - 0ch], ebx ; create EIP in old stack
696 movzx ebx, (IA32_TSS ptr [ecx])._CS
697 mov [eax - 08h], ebx ; create CS in old stack
698 mov ebx, (IA32_TSS ptr [ecx]).EFLAGS
699 bts ebx, 8
700 mov [eax - 04h], ebx ; create eflags in old stack
701 mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer
702 sub eax, 0ch ; minus 12 byte
703 mov (IA32_TSS ptr [ecx])._ESP, eax ; Set new stack pointer
704 ; Replace the EIP of interrupted task with stub function
705 mov eax, PageFaultStubFunction
706 mov (IA32_TSS ptr [ecx]).EIP, eax
707 ; Jump to the iretd so next page fault handler as a task will start again after iretd.
708 @Done2:
709 add esp, 4 ; skip ErrCode
710
711 jmp Return
712 PageFaultIdtHandlerSmmProfile ENDP
713
714 PageFaultStubFunction PROC
715 ;
716 ; we need clean TS bit in CR0 to execute
717 ; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.
718 ;
719 clts
720 iretd
721 PageFaultStubFunction ENDP
722
723 InitializeIDTSmmStackGuard PROC USES ebx
724 ;
725 ; If SMM Stack Guard feature is enabled, the Page Fault Exception entry in IDT
726 ; is a Task Gate Descriptor so that when a Page Fault Exception occurs,
727 ; the processors can use a known good stack in case stack is ran out.
728 ;
729 lea ebx, _SmiIDT + 14 * 8
730 lea edx, TaskGateDescriptor
731 mov eax, [edx]
732 mov [ebx], eax
733 mov eax, [edx + 4]
734 mov [ebx + 4], eax
735 ret
736 InitializeIDTSmmStackGuard ENDP
737
738 END