VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/EMAllA.asm@ 15

Last change on this file since 15 was 15, checked in by vboxsync, 18 years ago

header

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.7 KB
Line 
1;; @file
2; EM Assembly Routines.
3;
4
5; Copyright (C) 2006 InnoTek Systemberatung GmbH
6;
7; This file is part of VirtualBox Open Source Edition (OSE), as
8; available from http://www.virtualbox.org. This file is free software;
9; you can redistribute it and/or modify it under the terms of the GNU
10; General Public License as published by the Free Software Foundation,
11; in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
12; distribution. VirtualBox OSE is distributed in the hope that it will
13; be useful, but WITHOUT ANY WARRANTY of any kind.
14;
15; If you received this file as part of a commercial VirtualBox
16; distribution, then only the terms of your commercial VirtualBox
17; license agreement apply instead of the previous paragraph.
18
19;*******************************************************************************
20;* Header Files *
21;*******************************************************************************
22%include "VBox/nasm.mac"
23%include "VBox/err.mac"
24%include "VBox/x86.mac"
25
26;; @def MY_PTR_REG
27; The register we use for value pointers (And,Or,Dec,Inc).
28%ifdef __AMD64__
29%define MY_PTR_REG rcx
30%else
31%define MY_PTR_REG ecx
32%endif
33
34;; @def MY_RET_REG
35; The register we return the result in.
36%ifdef __AMD64__
37%define MY_RET_REG rax
38%else
39%define MY_RET_REG eax
40%endif
41
42BEGINCODE
43
44
45;;
46; Emulate CMP instruction, CDECL calling conv.
47; EMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint32_t u32Param2, size_t cb);
48;
49; @returns EFLAGS after the operation, only arithmetic flags is valid.
50; @param [esp + 04h] rdi rcx Param 1 - First parameter (Dst).
51; @param [esp + 08h] rsi edx Param 2 - Second parameter (Src).
52; @param [esp + 0ch] rdx r8 Param 3 - Size of parameters, only 1/2/4 is valid.
53;
54align 16
55BEGINPROC EMEmulateCmp
56%ifdef __AMD64__
57%ifdef __WIN64__
58 mov rax, r8 ; eax = size of parameters
59%else ; !__WIN64__
60 mov rax, rdx ; rax = size of parameters
61 mov rcx, rdi ; rcx = first parameter
62 mov rdx, rsi ; rdx = second parameter
63%endif ; !__WIN64__
64%else ; !__AMD64__
65 mov eax, [esp + 0ch] ; eax = size of parameters
66 mov ecx, [esp + 04h] ; ecx = first parameter
67 mov edx, [esp + 08h] ; edx = second parameter
68%endif
69
70 ; switch on size
71%ifdef __AMD64__
72 cmp al, 8
73 je short .do_qword ; 8 bytes variant
74%endif
75 cmp al, 4
76 je short .do_dword ; 4 bytes variant
77 cmp al, 2
78 je short .do_word ; 2 byte variant
79 cmp al, 1
80 je short .do_byte ; 1 bytes variant
81 int3
82
83 ; workers
84%ifdef __AMD64__
85.do_qword:
86 cmp rcx, rdx ; do 8 bytes CMP
87 jmp short .done
88%endif
89
90.do_dword:
91 cmp ecx, edx ; do 4 bytes CMP
92 jmp short .done
93
94.do_word:
95 cmp cx, dx ; do 2 bytes CMP
96 jmp short .done
97
98.do_byte:
99 cmp cl, dl ; do 1 byte CMP
100
101 ; collect flags and return.
102.done:
103 pushf
104 pop MY_RET_REG
105 retn
106ENDPROC EMEmulateCmp
107
108
109;;
110; Emulate AND instruction, CDECL calling conv.
111; EMDECL(uint32_t) EMEmulateAnd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
112;
113; @returns EFLAGS after the operation, only arithmetic flags is valid.
114; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
115; @param [esp + 08h] Param 2 - Second parameter.
116; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
117; @uses eax, ecx, edx
118;
119align 16
120BEGINPROC EMEmulateAnd
121%ifdef __AMD64__
122%ifdef __WIN64__
123 mov rax, r8 ; eax = size of parameters
124%else ; !__WIN64__
125 mov rax, rdx ; rax = size of parameters
126 mov rcx, rdi ; rcx = first parameter
127 mov rdx, rsi ; rdx = second parameter
128%endif ; !__WIN64__
129%else ; !__AMD64__
130 mov eax, [esp + 0ch] ; eax = size of parameters
131 mov ecx, [esp + 04h] ; ecx = first parameter
132 mov edx, [esp + 08h] ; edx = second parameter
133%endif
134
135 ; switch on size
136%ifdef __AMD64__
137 cmp al, 8
138 je short .do_qword ; 8 bytes variant
139%endif
140 cmp al, 4
141 je short .do_dword ; 4 bytes variant
142 cmp al, 2
143 je short .do_word ; 2 byte variant
144 cmp al, 1
145 je short .do_byte ; 1 bytes variant
146 int3
147
148 ; workers
149%ifdef __AMD64__
150.do_qword:
151 and [MY_PTR_REG], rdx ; do 8 bytes AND
152 jmp short .done
153%endif
154
155.do_dword:
156 and [MY_PTR_REG], edx ; do 4 bytes AND
157 jmp short .done
158
159.do_word:
160 and [MY_PTR_REG], dx ; do 2 bytes AND
161 jmp short .done
162
163.do_byte:
164 and [MY_PTR_REG], dl ; do 1 byte AND
165
166 ; collect flags and return.
167.done:
168 pushf
169 pop MY_RET_REG
170 retn
171ENDPROC EMEmulateAnd
172
173
174;;
175; Emulate OR instruction, CDECL calling conv.
176; EMDECL(uint32_t) EMEmulateOr(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
177;
178; @returns EFLAGS after the operation, only arithmetic flags is valid.
179; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
180; @param [esp + 08h] Param 2 - Second parameter.
181; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
182; @uses eax, ecx, edx
183;
184align 16
185BEGINPROC EMEmulateOr
186%ifdef __AMD64__
187%ifdef __WIN64__
188 mov rax, r8 ; eax = size of parameters
189%else ; !__WIN64__
190 mov rax, rdx ; rax = size of parameters
191 mov rcx, rdi ; rcx = first parameter
192 mov rdx, rsi ; rdx = second parameter
193%endif ; !__WIN64__
194%else ; !__AMD64__
195 mov eax, [esp + 0ch] ; eax = size of parameters
196 mov ecx, [esp + 04h] ; ecx = first parameter
197 mov edx, [esp + 08h] ; edx = second parameter
198%endif
199
200 ; switch on size
201%ifdef __AMD64__
202 cmp al, 8
203 je short .do_qword ; 8 bytes variant
204%endif
205 cmp al, 4
206 je short .do_dword ; 4 bytes variant
207 cmp al, 2
208 je short .do_word ; 2 byte variant
209 cmp al, 1
210 je short .do_byte ; 1 bytes variant
211 int3
212
213 ; workers
214%ifdef __AMD64__
215.do_qword:
216 or [MY_PTR_REG], rdx ; do 8 bytes OR
217 jmp short .done
218%endif
219
220.do_dword:
221 or [MY_PTR_REG], edx ; do 4 bytes OR
222 jmp short .done
223
224.do_word:
225 or [MY_PTR_REG], dx ; do 2 bytes OR
226 jmp short .done
227
228.do_byte:
229 or [MY_PTR_REG], dl ; do 1 byte OR
230
231 ; collect flags and return.
232.done:
233 pushf
234 pop MY_RET_REG
235 retn
236ENDPROC EMEmulateOr
237
238;;
239; Emulate XOR instruction, CDECL calling conv.
240; EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
241;
242; @returns EFLAGS after the operation, only arithmetic flags is valid.
243; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
244; @param [esp + 08h] Param 2 - Second parameter.
245; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
246; @uses eax, ecx, edx
247;
248align 16
249BEGINPROC EMEmulateXor
250%ifdef __AMD64__
251%ifdef __WIN64__
252 mov rax, r8 ; eax = size of parameters
253%else ; !__WIN64__
254 mov rax, rdx ; rax = size of parameters
255 mov rcx, rdi ; rcx = first parameter
256 mov rdx, rsi ; rdx = second parameter
257%endif ; !__WIN64__
258%else ; !__AMD64__
259 mov eax, [esp + 0ch] ; eax = size of parameters
260 mov ecx, [esp + 04h] ; ecx = first parameter
261 mov edx, [esp + 08h] ; edx = second parameter
262%endif
263
264 ; switch on size
265%ifdef __AMD64__
266 cmp al, 8
267 je short .do_qword ; 8 bytes variant
268%endif
269 cmp al, 4
270 je short .do_dword ; 4 bytes variant
271 cmp al, 2
272 je short .do_word ; 2 byte variant
273 cmp al, 1
274 je short .do_byte ; 1 bytes variant
275 int3
276
277 ; workers
278%ifdef __AMD64__
279.do_qword:
280 xor [MY_PTR_REG], rdx ; do 8 bytes XOR
281 jmp short .done
282%endif
283
284.do_dword:
285 xor [MY_PTR_REG], edx ; do 4 bytes XOR
286 jmp short .done
287
288.do_word:
289 xor [MY_PTR_REG], dx ; do 2 bytes XOR
290 jmp short .done
291
292.do_byte:
293 xor [MY_PTR_REG], dl ; do 1 byte XOR
294
295 ; collect flags and return.
296.done:
297 pushf
298 pop MY_RET_REG
299 retn
300ENDPROC EMEmulateXor
301
302;;
303; Emulate INC instruction, CDECL calling conv.
304; EMDECL(uint32_t) EMEmulateInc(uint32_t *pu32Param1, size_t cb);
305;
306; @returns EFLAGS after the operation, only arithmetic flags are valid.
307; @param [esp + 04h] rdi rcx Param 1 - First parameter - pointer to data item.
308; @param [esp + 08h] rsi rdx Param 2 - Size of parameters, only 1/2/4 is valid.
309; @uses eax, ecx, edx
310;
311align 16
312BEGINPROC EMEmulateInc
313%ifdef __AMD64__
314%ifdef __WIN64__
315 mov rax, rdx ; eax = size of parameters
316%else ; !__WIN64__
317 mov rax, rsi ; eax = size of parameters
318 mov rcx, rdi ; rcx = first parameter
319%endif ; !__WIN64__
320%else ; !__AMD64__
321 mov eax, [esp + 08h] ; eax = size of parameters
322 mov ecx, [esp + 04h] ; ecx = first parameter
323%endif
324
325 ; switch on size
326%ifdef __AMD64__
327 cmp al, 8
328 je short .do_qword ; 8 bytes variant
329%endif
330 cmp al, 4
331 je short .do_dword ; 4 bytes variant
332 cmp al, 2
333 je short .do_word ; 2 byte variant
334 cmp al, 1
335 je short .do_byte ; 1 bytes variant
336 int3
337
338 ; workers
339%ifdef __AMD64__
340.do_qword:
341 inc qword [MY_PTR_REG] ; do 8 bytes INC
342 jmp short .done
343%endif
344
345.do_dword:
346 inc dword [MY_PTR_REG] ; do 4 bytes INC
347 jmp short .done
348
349.do_word:
350 inc word [MY_PTR_REG] ; do 2 bytes INC
351 jmp short .done
352
353.do_byte:
354 inc byte [MY_PTR_REG] ; do 1 byte INC
355 jmp short .done
356
357 ; collect flags and return.
358.done:
359 pushf
360 pop MY_RET_REG
361 retn
362ENDPROC EMEmulateInc
363
364
365;;
366; Emulate DEC instruction, CDECL calling conv.
367; EMDECL(uint32_t) EMEmulateDec(uint32_t *pu32Param1, size_t cb);
368;
369; @returns EFLAGS after the operation, only arithmetic flags are valid.
370; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
371; @param [esp + 08h] Param 2 - Size of parameters, only 1/2/4 is valid.
372; @uses eax, ecx, edx
373;
374align 16
375BEGINPROC EMEmulateDec
376%ifdef __AMD64__
377%ifdef __WIN64__
378 mov rax, rdx ; eax = size of parameters
379%else ; !__WIN64__
380 mov rax, rsi ; eax = size of parameters
381 mov rcx, rdi ; rcx = first parameter
382%endif ; !__WIN64__
383%else ; !__AMD64__
384 mov eax, [esp + 08h] ; eax = size of parameters
385 mov ecx, [esp + 04h] ; ecx = first parameter
386%endif
387
388 ; switch on size
389%ifdef __AMD64__
390 cmp al, 8
391 je short .do_qword ; 8 bytes variant
392%endif
393 cmp al, 4
394 je short .do_dword ; 4 bytes variant
395 cmp al, 2
396 je short .do_word ; 2 byte variant
397 cmp al, 1
398 je short .do_byte ; 1 bytes variant
399 int3
400
401 ; workers
402%ifdef __AMD64__
403.do_qword:
404 dec qword [MY_PTR_REG] ; do 8 bytes DEC
405 jmp short .done
406%endif
407
408.do_dword:
409 dec dword [MY_PTR_REG] ; do 4 bytes DEC
410 jmp short .done
411
412.do_word:
413 dec word [MY_PTR_REG] ; do 2 bytes DEC
414 jmp short .done
415
416.do_byte:
417 dec byte [MY_PTR_REG] ; do 1 byte DEC
418 jmp short .done
419
420 ; collect flags and return.
421.done:
422 pushf
423 pop MY_RET_REG
424 retn
425ENDPROC EMEmulateDec
426
427;;
428; Emulate ADD instruction, CDECL calling conv.
429; EMDECL(uint32_t) EMEmulateAdd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
430;
431; @returns EFLAGS after the operation, only arithmetic flags is valid.
432; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
433; @param [esp + 08h] Param 2 - Second parameter.
434; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
435; @uses eax, ecx, edx
436;
437align 16
438BEGINPROC EMEmulateAdd
439%ifdef __AMD64__
440%ifdef __WIN64__
441 mov rax, r8 ; eax = size of parameters
442%else ; !__WIN64__
443 mov rax, rdx ; rax = size of parameters
444 mov rcx, rdi ; rcx = first parameter
445 mov rdx, rsi ; rdx = second parameter
446%endif ; !__WIN64__
447%else ; !__AMD64__
448 mov eax, [esp + 0ch] ; eax = size of parameters
449 mov ecx, [esp + 04h] ; ecx = first parameter
450 mov edx, [esp + 08h] ; edx = second parameter
451%endif
452
453 ; switch on size
454%ifdef __AMD64__
455 cmp al, 8
456 je short .do_qword ; 8 bytes variant
457%endif
458 cmp al, 4
459 je short .do_dword ; 4 bytes variant
460 cmp al, 2
461 je short .do_word ; 2 byte variant
462 cmp al, 1
463 je short .do_byte ; 1 bytes variant
464 int3
465
466 ; workers
467%ifdef __AMD64__
468.do_qword:
469 add [MY_PTR_REG], rdx ; do 8 bytes ADD
470 jmp short .done
471%endif
472
473.do_dword:
474 add [MY_PTR_REG], edx ; do 4 bytes ADD
475 jmp short .done
476
477.do_word:
478 add [MY_PTR_REG], dx ; do 2 bytes ADD
479 jmp short .done
480
481.do_byte:
482 add [MY_PTR_REG], dl ; do 1 byte ADD
483
484 ; collect flags and return.
485.done:
486 pushf
487 pop MY_RET_REG
488 retn
489ENDPROC EMEmulateAdd
490
491;;
492; Emulate ADC instruction, CDECL calling conv.
493; EMDECL(uint32_t) EMEmulateAdcWithCarrySet(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
494;
495; @returns EFLAGS after the operation, only arithmetic flags is valid.
496; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
497; @param [esp + 08h] Param 2 - Second parameter.
498; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
499; @uses eax, ecx, edx
500;
501align 16
502BEGINPROC EMEmulateAdcWithCarrySet
503%ifdef __AMD64__
504%ifdef __WIN64__
505 mov rax, r8 ; eax = size of parameters
506%else ; !__WIN64__
507 mov rax, rdx ; rax = size of parameters
508 mov rcx, rdi ; rcx = first parameter
509 mov rdx, rsi ; rdx = second parameter
510%endif ; !__WIN64__
511%else ; !__AMD64__
512 mov eax, [esp + 0ch] ; eax = size of parameters
513 mov ecx, [esp + 04h] ; ecx = first parameter
514 mov edx, [esp + 08h] ; edx = second parameter
515%endif
516
517 ; switch on size
518%ifdef __AMD64__
519 cmp al, 8
520 je short .do_qword ; 8 bytes variant
521%endif
522 cmp al, 4
523 je short .do_dword ; 4 bytes variant
524 cmp al, 2
525 je short .do_word ; 2 byte variant
526 cmp al, 1
527 je short .do_byte ; 1 bytes variant
528 int3
529
530 ; workers
531%ifdef __AMD64__
532.do_qword:
533 stc ; set carry flag
534 adc [MY_PTR_REG], rdx ; do 8 bytes ADC
535 jmp short .done
536%endif
537
538.do_dword:
539 stc ; set carry flag
540 adc [MY_PTR_REG], edx ; do 4 bytes ADC
541 jmp short .done
542
543.do_word:
544 stc ; set carry flag
545 adc [MY_PTR_REG], dx ; do 2 bytes ADC
546 jmp short .done
547
548.do_byte:
549 stc ; set carry flag
550 adc [MY_PTR_REG], dl ; do 1 byte ADC
551
552 ; collect flags and return.
553.done:
554 pushf
555 pop MY_RET_REG
556 retn
557ENDPROC EMEmulateAdcWithCarrySet
558
559;;
560; Emulate SUB instruction, CDECL calling conv.
561; EMDECL(uint32_t) EMEmulateSub(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
562;
563; @returns EFLAGS after the operation, only arithmetic flags is valid.
564; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
565; @param [esp + 08h] Param 2 - Second parameter.
566; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
567; @uses eax, ecx, edx
568;
569align 16
570BEGINPROC EMEmulateSub
571%ifdef __AMD64__
572%ifdef __WIN64__
573 mov rax, r8 ; eax = size of parameters
574%else ; !__WIN64__
575 mov rax, rdx ; rax = size of parameters
576 mov rcx, rdi ; rcx = first parameter
577 mov rdx, rsi ; rdx = second parameter
578%endif ; !__WIN64__
579%else ; !__AMD64__
580 mov eax, [esp + 0ch] ; eax = size of parameters
581 mov ecx, [esp + 04h] ; ecx = first parameter
582 mov edx, [esp + 08h] ; edx = second parameter
583%endif
584
585 ; switch on size
586%ifdef __AMD64__
587 cmp al, 8
588 je short .do_qword ; 8 bytes variant
589%endif
590 cmp al, 4
591 je short .do_dword ; 4 bytes variant
592 cmp al, 2
593 je short .do_word ; 2 byte variant
594 cmp al, 1
595 je short .do_byte ; 1 bytes variant
596 int3
597
598 ; workers
599%ifdef __AMD64__
600.do_qword:
601 sub [MY_PTR_REG], rdx ; do 8 bytes SUB
602 jmp short .done
603%endif
604
605.do_dword:
606 sub [MY_PTR_REG], edx ; do 4 bytes SUB
607 jmp short .done
608
609.do_word:
610 sub [MY_PTR_REG], dx ; do 2 bytes SUB
611 jmp short .done
612
613.do_byte:
614 sub [MY_PTR_REG], dl ; do 1 byte SUB
615
616 ; collect flags and return.
617.done:
618 pushf
619 pop MY_RET_REG
620 retn
621ENDPROC EMEmulateSub
Note: See TracBrowser for help on using the repository browser.

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