-
Notifications
You must be signed in to change notification settings - Fork 1
/
xmm386.asm
139 lines (115 loc) · 2.64 KB
/
xmm386.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
; xmm 386
.model tiny
.386
.code
PUBLIC C SWITCH32
PUBLIC C XMSCONTROL
EXTRN XMM_DISPATCH
XMSCONTROL PROC
push cx
push si
push di
push ds
push es
pushf
push ds ; arguments...
pop es
push cs ; cs:ds used by C code
pop ds
push es
push si
push dx
push ax ;
call XMM_DISPATCH
exit:
popf
pop es
pop ds
pop di
pop si
pop cx
retf
XMSCONTROL ENDP
SWITCH32 PROC
mov ax, ss
mov word ptr cs:[rm_ss], ax
mov ax, cs
mov word ptr cs:[rm_cs], ax
mov ax, sp
mov word ptr cs:[rm_sp], ax
xor eax, eax
mov ax, cs
shl eax, 4
add dword ptr cs:[cs_desc+2], eax ; base of cs in bytes
add dword ptr cs:[gdt_desc+2], eax ; address of GDT (physical linear address)
jmp enter_pmode
gdt_desc:
dw 20h
dd offset gdt
gdt:
dq 0 ; NULL descriptor
cs_desc:
dw 0ffffh ; limit FFFF
dw 00h ; base ?? 0000
db 00h ; ??00????
db 10011010b ; access byte [Ac 0, Readable DC 0 EX 1 S 1 Privl 00 Pr 1]
db 10001111b ; flags 1000 limit 1111 (4kb limit 16bit)
db 00 ; base 00??????
data_desc:
db 0ffh, 0ffh, 0, 0, 0, 10010010b, 11001111b, 0
stack_desc:
db 0ffh, 0ffh, 0, 0, 0, 10010010b, 11001111b, 0
.386p
enter_pmode:
lgdt fword ptr cs:[gdt_desc]
cli
in al, 70h
or al, 80h
out 70h, al
mov eax, cr0
or eax, 1
mov cr0, eax
; JMP FAR 08:PMODE_BLOCK => switch into 32bit mode!
db 66h
db 0eah
pmode_patch:
dd offset pmode_block
dw 08h
pmode_block:
mov bx, 10h ; set ds/es
mov ds, bx
mov es, bx
mov esi, 0b8000h
mov al, 'H'
mov ah, 28h
mov word ptr [esi], ax
mov al, 'e'
add esi, 2
mov word ptr [esi], ax
exit_pmode:
mov eax, cr0
and al, 0feh
mov cr0, eax
db 0eah ; jmp far
dw offset real_mode
rm_cs: dw 0
rm_ss: dw 0
rm_sp: dw 0
HelloBack db 'Hello world! We are in real mode!$'
.386
real_mode:
in al, 70h
and al, 07fh
out 70h, al
sti
mov ax, cs
mov sp, word ptr cs:[rm_sp]
mov ss, word ptr cs:[rm_ss] ; restore ss/sp complete..
mov ds, ax
mov es, ax
mov ax, 0deadh
ret
switch_32bit:
jmp real_mode
SWITCH32 ENDP
end