VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstX86-1A.asm@ 38636

Last change on this file since 38636 was 37955, checked in by vboxsync, 13 years ago

Moved VBox/x86.h/mac to iprt/x86.h/mac.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.7 KB
Line 
1; $Id: tstX86-1A.asm 37955 2011-07-14 12:23:02Z vboxsync $
2;; @file
3; X86 instruction set testcase #1.
4;
5
6;
7; Copyright (C) 2011 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
18
19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20; Header Files ;
21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22%include "iprt/asmdefs.mac"
23%include "iprt/x86.mac"
24
25;; @todo Move this to a header?
26struc TRAPINFO
27 .uTrapPC RTCCPTR_RES 1
28 .uResumePC RTCCPTR_RES 1
29 .u8TrapNo resb 1
30 .cbInstr resb 1
31 .au8Padding resb (RTCCPTR_CB*2 - 2)
32endstruc
33
34
35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
36; Global Variables ;
37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38BEGINDATA
39extern NAME(g_pbEfPage)
40extern NAME(g_pbEfExecPage)
41
42GLOBALNAME g_szAlpha
43 db "abcdefghijklmnopqrstuvwxyz", 0
44g_szAlpha_end:
45%define g_cchAlpha (g_szAlpha_end - NAME(g_szAlpha))
46 db 0, 0, 0,
47
48;;
49; The last global data item. We build this as we write the code.
50GLOBALNAME g_aTrapInfo
51
52
53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
54; Defined Constants And Macros ;
55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
56%define X86_XCPT_UD 6
57%define X86_XCPT_GP 13
58%define X86_XCPT_PF 14
59
60;; Reference a global variable
61%ifdef RT_ARCH_AMD64
62 %define REF_GLOBAL(a_Name) [NAME(a_Name) wrt rip]
63%else
64 %define REF_GLOBAL(a_Name) [NAME(a_Name)]
65%endif
66
67;;
68; Macro for recording a trapping instruction (simple).
69;
70; @param 1 The trap number.
71; @param 2+ The instruction which should trap.
72%macro ShouldTrap 2+
73%%trap:
74 %2
75%%trap_end:
76 mov eax, __LINE__
77 jmp .failed
78BEGINDATA
79%%trapinfo: istruc TRAPINFO
80 at TRAPINFO.uTrapPC, RTCCPTR_DEF %%trap
81 at TRAPINFO.uResumePC, RTCCPTR_DEF %%resume
82 at TRAPINFO.u8TrapNo, db %1
83 at TRAPINFO.cbInstr, db (%%trap_end - %%trap)
84iend
85BEGINCODE
86%%resume:
87%endmacro
88
89
90
91BEGINCODE
92
93;;
94; Loads all general registers except xBP and xSP with unique values.
95;
96x861_LoadUniqueRegValues:
97%ifdef RT_ARCH_AMD64
98 mov rax, 00000000000000000h
99 mov rcx, 01111111111111111h
100 mov rdx, 02222222222222222h
101 mov rbx, 03333333333333333h
102 mov rsi, 06666666666666666h
103 mov rdi, 07777777777777777h
104 mov r8, 08888888888888888h
105 mov r9, 09999999999999999h
106 mov r10, 0aaaaaaaaaaaaaaaah
107 mov r11, 0bbbbbbbbbbbbbbbbh
108 mov r12, 0cccccccccccccccch
109 mov r13, 0ddddddddddddddddh
110 mov r14, 0eeeeeeeeeeeeeeeeh
111 mov r15, 0ffffffffffffffffh
112%else
113 mov eax, 000000000h
114 mov ecx, 011111111h
115 mov edx, 022222222h
116 mov ebx, 033333333h
117 mov esi, 066666666h
118 mov edi, 077777777h
119%endif
120 ret
121; end x861_LoadUniqueRegValues
122
123
124;;
125; Clears all general registers except xBP and xSP.
126;
127x861_ClearRegisters:
128 xor eax, eax
129 xor ebx, ebx
130 xor ecx, ecx
131 xor edx, edx
132 xor esi, esi
133 xor edi, edi
134%ifdef RT_ARCH_AMD64
135 xor r8, r8
136 xor r9, r9
137 xor r10, r10
138 xor r11, r11
139 xor r12, r12
140 xor r13, r13
141 xor r14, r14
142 xor r15, r15
143%endif
144 ret
145; x861_ClearRegisters
146
147
148BEGINPROC x861_Test1
149 push xBP
150 mov xBP, xSP
151 pushf
152 push xBX
153 push xCX
154 push xDX
155 push xSI
156 push xDI
157%ifdef RT_ARCH_AMD64
158 push r8
159 push r9
160 push r10
161 push r11
162 push r12
163 push r13
164 push r14
165 push r15
166%endif
167
168 ;
169 ; Odd push behavior
170 ;
171%if 0 ; Seems to be so on AMD only
172%ifdef RT_ARCH_X86
173 ; upper word of a 'push cs' is cleared.
174 mov eax, __LINE__
175 mov dword [esp - 4], 0f0f0f0fh
176 push cs
177 pop ecx
178 mov bx, cs
179 and ebx, 0000ffffh
180 cmp ecx, ebx
181 jne .failed
182
183 ; upper word of a 'push ds' is cleared.
184 mov eax, __LINE__
185 mov dword [esp - 4], 0f0f0f0fh
186 push ds
187 pop ecx
188 mov bx, ds
189 and ebx, 0000ffffh
190 cmp ecx, ebx
191 jne .failed
192
193 ; upper word of a 'push es' is cleared.
194 mov eax, __LINE__
195 mov dword [esp - 4], 0f0f0f0fh
196 push es
197 pop ecx
198 mov bx, es
199 and ebx, 0000ffffh
200 cmp ecx, ebx
201 jne .failed
202%endif ; RT_ARCH_X86
203
204 ; The upper part of a 'push fs' is cleared.
205 mov eax, __LINE__
206 xor ecx, ecx
207 not xCX
208 push xCX
209 pop xCX
210 push fs
211 pop xCX
212 mov bx, fs
213 and ebx, 0000ffffh
214 cmp xCX, xBX
215 jne .failed
216
217 ; The upper part of a 'push gs' is cleared.
218 mov eax, __LINE__
219 xor ecx, ecx
220 not xCX
221 push xCX
222 pop xCX
223 push gs
224 pop xCX
225 mov bx, gs
226 and ebx, 0000ffffh
227 cmp xCX, xBX
228 jne .failed
229%endif
230
231%ifdef RT_ARCH_AMD64
232 ; REX.B works with 'push r64'.
233 call x861_LoadUniqueRegValues
234 mov eax, __LINE__
235 push rcx
236 pop rdx
237 cmp rdx, rcx
238 jne .failed
239
240 call x861_LoadUniqueRegValues
241 mov eax, __LINE__
242 db 041h ; REX.B
243 push rcx
244 pop rdx
245 cmp rdx, r9
246 jne .failed
247
248 call x861_LoadUniqueRegValues
249 mov eax, __LINE__
250 db 042h ; REX.X
251 push rcx
252 pop rdx
253 cmp rdx, rcx
254 jne .failed
255
256 call x861_LoadUniqueRegValues
257 mov eax, __LINE__
258 db 044h ; REX.R
259 push rcx
260 pop rdx
261 cmp rdx, rcx
262 jne .failed
263
264 call x861_LoadUniqueRegValues
265 mov eax, __LINE__
266 db 048h ; REX.W
267 push rcx
268 pop rdx
269 cmp rdx, rcx
270 jne .failed
271
272 call x861_LoadUniqueRegValues
273 mov eax, __LINE__
274 db 04fh ; REX.*
275 push rcx
276 pop rdx
277 cmp rdx, r9
278 jne .failed
279%endif
280
281 ;
282 ; Zero extening when moving from a segreg as well as memory access sizes.
283 ;
284 call x861_LoadUniqueRegValues
285 mov eax, __LINE__
286 mov ecx, ds
287 shr xCX, 16
288 cmp xCX, 0
289 jnz .failed
290
291%ifdef RT_ARCH_AMD64
292 call x861_LoadUniqueRegValues
293 mov eax, __LINE__
294 mov rcx, ds
295 shr rcx, 16
296 cmp rcx, 0
297 jnz .failed
298%endif
299
300 call x861_LoadUniqueRegValues
301 mov eax, __LINE__
302 mov xDX, xCX
303 mov cx, ds
304 shr xCX, 16
305 shr xDX, 16
306 cmp xCX, xDX
307 jnz .failed
308
309 ; Loading is always a word access.
310 mov eax, __LINE__
311 mov xDI, REF_GLOBAL(g_pbEfPage)
312 lea xDI, [xDI + 0x1000 - 2]
313 mov xDX, es
314 mov [xDI], dx
315 mov es, [xDI] ; should not crash
316
317 ; Saving is always a word access.
318 mov eax, __LINE__
319 mov xDI, REF_GLOBAL(g_pbEfPage)
320 mov dword [xDI + 0x1000 - 4], -1
321 mov [xDI + 0x1000 - 2], ss ; Should not crash.
322 mov bx, ss
323 mov cx, [xDI + 0x1000 - 2]
324 cmp cx, bx
325 jne .failed
326
327%ifdef RT_ARCH_AMD64
328 ; Check that the rex.R and rex.W bits don't have any influence over a memory write.
329 call x861_ClearRegisters
330 mov eax, __LINE__
331 mov xDI, REF_GLOBAL(g_pbEfPage)
332 mov dword [xDI + 0x1000 - 4], -1
333 db 04ah
334 mov [xDI + 0x1000 - 2], ss ; Should not crash.
335 mov bx, ss
336 mov cx, [xDI + 0x1000 - 2]
337 cmp cx, bx
338 jne .failed
339%endif
340
341
342 ;
343 ; Check what happens when both string prefixes are used.
344 ;
345 cld
346 mov dx, ds
347 mov es, dx
348
349 ; check that repne scasb (al=0) behaves like expected.
350 lea xDI, REF_GLOBAL(g_szAlpha)
351 xor eax, eax ; find the end
352 mov ecx, g_cchAlpha + 1
353 repne scasb
354 cmp ecx, 1
355 mov eax, __LINE__
356 jne .failed
357
358 ; check that repe scasb (al=0) behaves like expected.
359 lea xDI, REF_GLOBAL(g_szAlpha)
360 xor eax, eax ; find the end
361 mov ecx, g_cchAlpha + 1
362 repe scasb
363 cmp ecx, g_cchAlpha
364 mov eax, __LINE__
365 jne .failed
366
367 ; repne is last, it wins.
368 lea xDI, REF_GLOBAL(g_szAlpha)
369 xor eax, eax ; find the end
370 mov ecx, g_cchAlpha + 1
371 db 0f3h ; repe - ignored
372 db 0f2h ; repne
373 scasb
374 cmp ecx, 1
375 mov eax, __LINE__
376 jne .failed
377
378 ; repe is last, it wins.
379 lea xDI, REF_GLOBAL(g_szAlpha)
380 xor eax, eax ; find the end
381 mov ecx, g_cchAlpha + 1
382 db 0f2h ; repne - ignored
383 db 0f3h ; repe
384 scasb
385 cmp ecx, g_cchAlpha
386 mov eax, __LINE__
387 jne .failed
388
389 ;
390 ; Check if stosb works with both prefixes.
391 ;
392 cld
393 mov dx, ds
394 mov es, dx
395 mov xDI, REF_GLOBAL(g_pbEfPage)
396 xor eax, eax
397 mov ecx, 01000h
398 rep stosb
399
400 mov xDI, REF_GLOBAL(g_pbEfPage)
401 mov ecx, 4
402 mov eax, 0ffh
403 db 0f2h ; repne
404 stosb
405 mov eax, __LINE__
406 cmp ecx, 0
407 jne .failed
408 mov eax, __LINE__
409 mov xDI, REF_GLOBAL(g_pbEfPage)
410 cmp dword [xDI], 0ffffffffh
411 jne .failed
412 cmp dword [xDI+4], 0
413 jne .failed
414
415 mov xDI, REF_GLOBAL(g_pbEfPage)
416 mov ecx, 4
417 mov eax, 0feh
418 db 0f3h ; repe
419 stosb
420 mov eax, __LINE__
421 cmp ecx, 0
422 jne .failed
423 mov eax, __LINE__
424 mov xDI, REF_GLOBAL(g_pbEfPage)
425 cmp dword [xDI], 0fefefefeh
426 jne .failed
427 cmp dword [xDI+4], 0
428 jne .failed
429
430 ;
431 ; String operations shouldn't crash because of an invalid address if rCX is 0.
432 ;
433 mov eax, __LINE__
434 cld
435 mov dx, ds
436 mov es, dx
437 mov xDI, REF_GLOBAL(g_pbEfPage)
438 xor xCX, xCX
439 rep stosb ; no trap
440
441 ;
442 ; INS/OUTS will trap in ring-3 even when rCX is 0. (ASSUMES IOPL < 3)
443 ;
444 mov eax, __LINE__
445 cld
446 mov dx, ss
447 mov ss, dx
448 mov xDI, xSP
449 xor xCX, xCX
450 ShouldTrap X86_XCPT_GP, rep insb
451
452 ;
453 ; SMSW can get to the whole of CR0.
454 ;
455 mov eax, __LINE__
456 xor xBX, xBX
457 smsw xBX
458 test ebx, X86_CR0_PG
459 jz .failed
460 test ebx, X86_CR0_PE
461 jz .failed
462
463 ;
464 ; Will the CPU decode the whole r/m+sib stuff before signalling a lock
465 ; prefix error? Use the EF exec page and a LOCK ADD CL,[rDI + disp32]
466 ; instruction at the very end of it.
467 ;
468 mov eax, __LINE__
469 mov xDI, REF_GLOBAL(g_pbEfExecPage)
470 add xDI, 1000h - 8h
471 mov byte [xDI+0], 0f0h
472 mov byte [xDI+1], 002h
473 mov byte [xDI+2], 08fh
474 mov dword [xDI+3], 000000000h
475 mov byte [xDI+7], 0cch
476 ShouldTrap X86_XCPT_UD, call xDI
477
478 mov eax, __LINE__
479 mov xDI, REF_GLOBAL(g_pbEfExecPage)
480 add xDI, 1000h - 7h
481 mov byte [xDI+0], 0f0h
482 mov byte [xDI+1], 002h
483 mov byte [xDI+2], 08Fh
484 mov dword [xDI+3], 000000000h
485 ShouldTrap X86_XCPT_UD, call xDI
486
487 mov eax, __LINE__
488 mov xDI, REF_GLOBAL(g_pbEfExecPage)
489 add xDI, 1000h - 4h
490 mov byte [xDI+0], 0f0h
491 mov byte [xDI+1], 002h
492 mov byte [xDI+2], 08Fh
493 mov byte [xDI+3], 000h
494 ShouldTrap X86_XCPT_PF, call xDI
495
496 mov eax, __LINE__
497 mov xDI, REF_GLOBAL(g_pbEfExecPage)
498 add xDI, 1000h - 6h
499 mov byte [xDI+0], 0f0h
500 mov byte [xDI+1], 002h
501 mov byte [xDI+2], 08Fh
502 mov byte [xDI+3], 00h
503 mov byte [xDI+4], 00h
504 mov byte [xDI+5], 00h
505 ShouldTrap X86_XCPT_PF, call xDI
506
507 mov eax, __LINE__
508 mov xDI, REF_GLOBAL(g_pbEfExecPage)
509 add xDI, 1000h - 5h
510 mov byte [xDI+0], 0f0h
511 mov byte [xDI+1], 002h
512 mov byte [xDI+2], 08Fh
513 mov byte [xDI+3], 00h
514 mov byte [xDI+4], 00h
515 ShouldTrap X86_XCPT_PF, call xDI
516
517 mov eax, __LINE__
518 mov xDI, REF_GLOBAL(g_pbEfExecPage)
519 add xDI, 1000h - 4h
520 mov byte [xDI+0], 0f0h
521 mov byte [xDI+1], 002h
522 mov byte [xDI+2], 08Fh
523 mov byte [xDI+3], 00h
524 ShouldTrap X86_XCPT_PF, call xDI
525
526 mov eax, __LINE__
527 mov xDI, REF_GLOBAL(g_pbEfExecPage)
528 add xDI, 1000h - 3h
529 mov byte [xDI+0], 0f0h
530 mov byte [xDI+1], 002h
531 mov byte [xDI+2], 08Fh
532 ShouldTrap X86_XCPT_PF, call xDI
533
534 mov eax, __LINE__
535 mov xDI, REF_GLOBAL(g_pbEfExecPage)
536 add xDI, 1000h - 2h
537 mov byte [xDI+0], 0f0h
538 mov byte [xDI+1], 002h
539 ShouldTrap X86_XCPT_PF, call xDI
540
541 mov eax, __LINE__
542 mov xDI, REF_GLOBAL(g_pbEfExecPage)
543 add xDI, 1000h - 1h
544 mov byte [xDI+0], 0f0h
545 ShouldTrap X86_XCPT_PF, call xDI
546
547
548
549.success:
550 xor eax, eax
551.return:
552%ifdef RT_ARCH_AMD64
553 pop r15
554 pop r14
555 pop r13
556 pop r12
557 pop r11
558 pop r10
559 pop r9
560 pop r8
561%endif
562 pop xDI
563 pop xSI
564 pop xDX
565 pop xCX
566 pop xBX
567 popf
568 leave
569 ret
570
571.failed2:
572 mov eax, -1
573.failed:
574 jmp .return
575ENDPROC x861_Test1
576
577
578;;
579; Terminate the trap info array with a NIL entry.
580BEGINDATA
581GLOBALNAME g_aTrapInfoEnd
582istruc TRAPINFO
583 at TRAPINFO.uTrapPC, RTCCPTR_DEF 0
584 at TRAPINFO.uResumePC, RTCCPTR_DEF 0
585 at TRAPINFO.u8TrapNo, db 0
586 at TRAPINFO.cbInstr, db 0
587iend
588
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