1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines which are related to
36 * instruction decoding and accessess of immediate data via IP. etc.
38 ****************************************************************************/
41 #include "x86emu/x86emui.h"
43 /*----------------------------- Implementation ----------------------------*/
45 /****************************************************************************
47 Handles any pending asychronous interrupts.
48 ****************************************************************************/
50 x86emu_intr_handle(void)
54 if (M
.x86
.intr
& INTR_SYNCH
) {
56 if (_X86EMU_intrTab
[intno
]) {
57 (*_X86EMU_intrTab
[intno
]) (intno
);
60 push_word((u16
) M
.x86
.R_FLG
);
63 push_word(M
.x86
.R_CS
);
64 M
.x86
.R_CS
= mem_access_word(intno
* 4 + 2);
65 push_word(M
.x86
.R_IP
);
66 M
.x86
.R_IP
= mem_access_word(intno
* 4);
72 /****************************************************************************
74 intrnum - Interrupt number to raise
77 Raise the specified interrupt to be handled before the execution of the
79 ****************************************************************************/
81 x86emu_intr_raise(u8 intrnum
)
83 M
.x86
.intno
= intrnum
;
84 M
.x86
.intr
|= INTR_SYNCH
;
87 /****************************************************************************
89 Main execution loop for the emulator. We return from here when the system
90 halts, which is normally caused by a stack fault when we return from the
91 original real mode call.
92 ****************************************************************************/
99 DB(x86emu_end_instr();
103 DB(if (CHECK_IP_FETCH())
104 x86emu_check_ip_access();)
105 /* If debugging, save the IP and CS values. */
106 SAVE_IP_CS(M
.x86
.R_CS
, M
.x86
.R_IP
);
107 INC_DECODED_INST_LEN(1);
109 if (M
.x86
.intr
& INTR_HALTED
) {
110 DB(if (M
.x86
.R_SP
!= 0) {
111 printk("halted\n"); X86EMU_trace_regs();}
114 printk("Service completed successfully\n");}
118 if (((M
.x86
.intr
& INTR_SYNCH
) &&
119 (M
.x86
.intno
== 0 || M
.x86
.intno
== 2)) ||
120 !ACCESS_FLAG(F_IF
)) {
121 x86emu_intr_handle();
124 op1
= (*sys_rdb
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
125 (*x86emu_optab
[op1
]) (op1
);
126 if (M
.x86
.debug
& DEBUG_EXIT
) {
127 M
.x86
.debug
&= ~DEBUG_EXIT
;
133 /****************************************************************************
135 Halts the system by setting the halted system flag.
136 ****************************************************************************/
138 X86EMU_halt_sys(void)
140 M
.x86
.intr
|= INTR_HALTED
;
143 /****************************************************************************
145 mod - Mod value from decoded byte
146 regh - Reg h value from decoded byte
147 regl - Reg l value from decoded byte
150 Raise the specified interrupt to be handled before the execution of the
153 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
154 ****************************************************************************/
156 fetch_decode_modrm(int *mod
, int *regh
, int *regl
)
160 DB(if (CHECK_IP_FETCH())
161 x86emu_check_ip_access();)
162 fetched
= (*sys_rdb
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
163 INC_DECODED_INST_LEN(1);
164 *mod
= (fetched
>> 6) & 0x03;
165 *regh
= (fetched
>> 3) & 0x07;
166 *regl
= (fetched
>> 0) & 0x07;
169 /****************************************************************************
171 Immediate byte value read from instruction queue
174 This function returns the immediate byte from the instruction queue, and
175 moves the instruction pointer to the next value.
177 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
178 ****************************************************************************/
184 DB(if (CHECK_IP_FETCH())
185 x86emu_check_ip_access();)
186 fetched
= (*sys_rdb
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
187 INC_DECODED_INST_LEN(1);
191 /****************************************************************************
193 Immediate word value read from instruction queue
196 This function returns the immediate byte from the instruction queue, and
197 moves the instruction pointer to the next value.
199 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
200 ****************************************************************************/
206 DB(if (CHECK_IP_FETCH())
207 x86emu_check_ip_access();)
208 fetched
= (*sys_rdw
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
210 INC_DECODED_INST_LEN(2);
214 /****************************************************************************
216 Immediate lone value read from instruction queue
219 This function returns the immediate byte from the instruction queue, and
220 moves the instruction pointer to the next value.
222 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
223 ****************************************************************************/
229 DB(if (CHECK_IP_FETCH())
230 x86emu_check_ip_access();)
231 fetched
= (*sys_rdl
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
233 INC_DECODED_INST_LEN(4);
237 /****************************************************************************
239 Value of the default data segment
242 Inline function that returns the default data segment for the current
245 On the x86 processor, the default segment is not always DS if there is
246 no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
247 addresses relative to SS (ie: on the stack). So, at the minimum, all
248 decodings of addressing modes would have to set/clear a bit describing
249 whether the access is relative to DS or SS. That is the function of the
250 cpu-state-varible M.x86.mode. There are several potential states:
252 repe prefix seen (handled elsewhere)
253 repne prefix seen (ditto)
262 ds/ss select (in absense of override)
264 Each of the above 7 items are handled with a bit in the mode field.
265 ****************************************************************************/
267 get_data_segment(void)
269 #define GET_SEGMENT(segment)
270 switch (M
.x86
.mode
& SYSMODE_SEGMASK
) {
271 case 0: /* default case: use ds register */
272 case SYSMODE_SEGOVR_DS
:
273 case SYSMODE_SEGOVR_DS
| SYSMODE_SEG_DS_SS
:
275 case SYSMODE_SEG_DS_SS
: /* non-overridden, use ss register */
277 case SYSMODE_SEGOVR_CS
:
278 case SYSMODE_SEGOVR_CS
| SYSMODE_SEG_DS_SS
:
280 case SYSMODE_SEGOVR_ES
:
281 case SYSMODE_SEGOVR_ES
| SYSMODE_SEG_DS_SS
:
283 case SYSMODE_SEGOVR_FS
:
284 case SYSMODE_SEGOVR_FS
| SYSMODE_SEG_DS_SS
:
286 case SYSMODE_SEGOVR_GS
:
287 case SYSMODE_SEGOVR_GS
| SYSMODE_SEG_DS_SS
:
289 case SYSMODE_SEGOVR_SS
:
290 case SYSMODE_SEGOVR_SS
| SYSMODE_SEG_DS_SS
:
294 printk("error: should not happen: multiple overrides.\n");
301 /****************************************************************************
303 offset - Offset to load data from
306 Byte value read from the absolute memory location.
308 NOTE: Do not inline this function as (*sys_rdX) is already inline!
309 ****************************************************************************/
311 fetch_data_byte(uint offset
)
314 if (CHECK_DATA_ACCESS())
315 x86emu_check_data_access((u16
) get_data_segment(), offset
);
317 return (*sys_rdb
) ((get_data_segment() << 4) + offset
);
320 /****************************************************************************
322 offset - Offset to load data from
325 Word value read from the absolute memory location.
327 NOTE: Do not inline this function as (*sys_rdX) is already inline!
328 ****************************************************************************/
330 fetch_data_word(uint offset
)
333 if (CHECK_DATA_ACCESS())
334 x86emu_check_data_access((u16
) get_data_segment(), offset
);
336 return (*sys_rdw
) ((get_data_segment() << 4) + offset
);
339 /****************************************************************************
341 offset - Offset to load data from
344 Long value read from the absolute memory location.
346 NOTE: Do not inline this function as (*sys_rdX) is already inline!
347 ****************************************************************************/
349 fetch_data_long(uint offset
)
352 if (CHECK_DATA_ACCESS())
353 x86emu_check_data_access((u16
) get_data_segment(), offset
);
355 return (*sys_rdl
) ((get_data_segment() << 4) + offset
);
358 /****************************************************************************
360 segment - Segment to load data from
361 offset - Offset to load data from
364 Byte value read from the absolute memory location.
366 NOTE: Do not inline this function as (*sys_rdX) is already inline!
367 ****************************************************************************/
369 fetch_data_byte_abs(uint segment
, uint offset
)
372 if (CHECK_DATA_ACCESS())
373 x86emu_check_data_access(segment
, offset
);
375 return (*sys_rdb
) (((u32
) segment
<< 4) + offset
);
378 /****************************************************************************
380 segment - Segment to load data from
381 offset - Offset to load data from
384 Word value read from the absolute memory location.
386 NOTE: Do not inline this function as (*sys_rdX) is already inline!
387 ****************************************************************************/
389 fetch_data_word_abs(uint segment
, uint offset
)
392 if (CHECK_DATA_ACCESS())
393 x86emu_check_data_access(segment
, offset
);
395 return (*sys_rdw
) (((u32
) segment
<< 4) + offset
);
398 /****************************************************************************
400 segment - Segment to load data from
401 offset - Offset to load data from
404 Long value read from the absolute memory location.
406 NOTE: Do not inline this function as (*sys_rdX) is already inline!
407 ****************************************************************************/
409 fetch_data_long_abs(uint segment
, uint offset
)
412 if (CHECK_DATA_ACCESS())
413 x86emu_check_data_access(segment
, offset
);
415 return (*sys_rdl
) (((u32
) segment
<< 4) + offset
);
418 /****************************************************************************
420 offset - Offset to store data at
424 Writes a word value to an segmented memory location. The segment used is
425 the current 'default' segment, which may have been overridden.
427 NOTE: Do not inline this function as (*sys_wrX) is already inline!
428 ****************************************************************************/
430 store_data_byte(uint offset
, u8 val
)
433 if (CHECK_DATA_ACCESS())
434 x86emu_check_data_access((u16
) get_data_segment(), offset
);
436 (*sys_wrb
) ((get_data_segment() << 4) + offset
, val
);
439 /****************************************************************************
441 offset - Offset to store data at
445 Writes a word value to an segmented memory location. The segment used is
446 the current 'default' segment, which may have been overridden.
448 NOTE: Do not inline this function as (*sys_wrX) is already inline!
449 ****************************************************************************/
451 store_data_word(uint offset
, u16 val
)
454 if (CHECK_DATA_ACCESS())
455 x86emu_check_data_access((u16
) get_data_segment(), offset
);
457 (*sys_wrw
) ((get_data_segment() << 4) + offset
, val
);
460 /****************************************************************************
462 offset - Offset to store data at
466 Writes a long value to an segmented memory location. The segment used is
467 the current 'default' segment, which may have been overridden.
469 NOTE: Do not inline this function as (*sys_wrX) is already inline!
470 ****************************************************************************/
472 store_data_long(uint offset
, u32 val
)
475 if (CHECK_DATA_ACCESS())
476 x86emu_check_data_access((u16
) get_data_segment(), offset
);
478 (*sys_wrl
) ((get_data_segment() << 4) + offset
, val
);
481 /****************************************************************************
483 segment - Segment to store data at
484 offset - Offset to store data at
488 Writes a byte value to an absolute memory location.
490 NOTE: Do not inline this function as (*sys_wrX) is already inline!
491 ****************************************************************************/
493 store_data_byte_abs(uint segment
, uint offset
, u8 val
)
496 if (CHECK_DATA_ACCESS())
497 x86emu_check_data_access(segment
, offset
);
499 (*sys_wrb
) (((u32
) segment
<< 4) + offset
, val
);
502 /****************************************************************************
504 segment - Segment to store data at
505 offset - Offset to store data at
509 Writes a word value to an absolute memory location.
511 NOTE: Do not inline this function as (*sys_wrX) is already inline!
512 ****************************************************************************/
514 store_data_word_abs(uint segment
, uint offset
, u16 val
)
517 if (CHECK_DATA_ACCESS())
518 x86emu_check_data_access(segment
, offset
);
520 (*sys_wrw
) (((u32
) segment
<< 4) + offset
, val
);
523 /****************************************************************************
525 segment - Segment to store data at
526 offset - Offset to store data at
530 Writes a long value to an absolute memory location.
532 NOTE: Do not inline this function as (*sys_wrX) is already inline!
533 ****************************************************************************/
535 store_data_long_abs(uint segment
, uint offset
, u32 val
)
538 if (CHECK_DATA_ACCESS())
539 x86emu_check_data_access(segment
, offset
);
541 (*sys_wrl
) (((u32
) segment
<< 4) + offset
, val
);
544 /****************************************************************************
546 reg - Register to decode
549 Pointer to the appropriate register
552 Return a pointer to the register given by the R/RM field of the
553 modrm byte, for byte operands. Also enables the decoding of instructions.
554 ****************************************************************************/
556 decode_rm_byte_register(int reg
)
585 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
588 /****************************************************************************
590 reg - Register to decode
593 Pointer to the appropriate register
596 Return a pointer to the register given by the R/RM field of the
597 modrm byte, for word operands. Also enables the decoding of instructions.
598 ****************************************************************************/
600 decode_rm_word_register(int reg
)
629 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
632 /****************************************************************************
634 reg - Register to decode
637 Pointer to the appropriate register
640 Return a pointer to the register given by the R/RM field of the
641 modrm byte, for dword operands. Also enables the decoding of instructions.
642 ****************************************************************************/
644 decode_rm_long_register(int reg
)
648 DECODE_PRINTF("EAX");
651 DECODE_PRINTF("ECX");
654 DECODE_PRINTF("EDX");
657 DECODE_PRINTF("EBX");
660 DECODE_PRINTF("ESP");
663 DECODE_PRINTF("EBP");
666 DECODE_PRINTF("ESI");
669 DECODE_PRINTF("EDI");
673 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
676 /****************************************************************************
678 reg - Register to decode
681 Pointer to the appropriate register
684 Return a pointer to the register given by the R/RM field of the
685 modrm byte, for word operands, modified from above for the weirdo
686 special case of segreg operands. Also enables the decoding of instructions.
687 ****************************************************************************/
689 decode_rm_seg_register(int reg
)
712 DECODE_PRINTF("ILLEGAL SEGREG");
716 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
721 * return offset from the SIB Byte
724 decode_sib_address(int sib
, int mod
)
726 u32 base
= 0, i
= 0, scale
= 1;
728 switch (sib
& 0x07) {
730 DECODE_PRINTF("[EAX]");
734 DECODE_PRINTF("[ECX]");
738 DECODE_PRINTF("[EDX]");
742 DECODE_PRINTF("[EBX]");
746 DECODE_PRINTF("[ESP]");
748 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
752 base
= fetch_long_imm();
753 DECODE_PRINTF2("%08x", base
);
756 DECODE_PRINTF("[EBP]");
758 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
762 DECODE_PRINTF("[ESI]");
766 DECODE_PRINTF("[EDI]");
770 switch ((sib
>> 3) & 0x07) {
772 DECODE_PRINTF("[EAX");
776 DECODE_PRINTF("[ECX");
780 DECODE_PRINTF("[EDX");
784 DECODE_PRINTF("[EBX");
791 DECODE_PRINTF("[EBP");
795 DECODE_PRINTF("[ESI");
799 DECODE_PRINTF("[EDI");
803 scale
= 1 << ((sib
>> 6) & 0x03);
804 if (((sib
>> 3) & 0x07) != 4) {
809 DECODE_PRINTF2("*%d]", scale
);
812 return base
+ (i
* scale
);
815 /****************************************************************************
817 rm - RM value to decode
820 Offset in memory for the address decoding
823 Return the offset given by mod=00 addressing. Also enables the
824 decoding of instructions.
826 NOTE: The code which specifies the corresponding segment (ds vs ss)
827 below in the case of [BP+..]. The assumption here is that at the
828 point that this subroutine is called, the bit corresponding to
829 SYSMODE_SEG_DS_SS will be zero. After every instruction
830 except the segment override instructions, this bit (as well
831 as any bits indicating segment overrides) will be clear. So
832 if a SS access is needed, set this bit. Otherwise, DS access
833 occurs (unless any of the segment override bits are set).
834 ****************************************************************************/
836 decode_rm00_address(int rm
)
841 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
842 /* 32-bit addressing */
845 DECODE_PRINTF("[EAX]");
848 DECODE_PRINTF("[ECX]");
851 DECODE_PRINTF("[EDX]");
854 DECODE_PRINTF("[EBX]");
857 sib
= fetch_byte_imm();
858 return decode_sib_address(sib
, 0);
860 offset
= fetch_long_imm();
861 DECODE_PRINTF2("[%08x]", offset
);
864 DECODE_PRINTF("[ESI]");
867 DECODE_PRINTF("[EDI]");
873 /* 16-bit addressing */
876 DECODE_PRINTF("[BX+SI]");
877 return (M
.x86
.R_BX
+ M
.x86
.R_SI
) & 0xffff;
879 DECODE_PRINTF("[BX+DI]");
880 return (M
.x86
.R_BX
+ M
.x86
.R_DI
) & 0xffff;
882 DECODE_PRINTF("[BP+SI]");
883 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
884 return (M
.x86
.R_BP
+ M
.x86
.R_SI
) & 0xffff;
886 DECODE_PRINTF("[BP+DI]");
887 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
888 return (M
.x86
.R_BP
+ M
.x86
.R_DI
) & 0xffff;
890 DECODE_PRINTF("[SI]");
893 DECODE_PRINTF("[DI]");
896 offset
= fetch_word_imm();
897 DECODE_PRINTF2("[%04x]", offset
);
900 DECODE_PRINTF("[BX]");
908 /****************************************************************************
910 rm - RM value to decode
913 Offset in memory for the address decoding
916 Return the offset given by mod=01 addressing. Also enables the
917 decoding of instructions.
918 ****************************************************************************/
920 decode_rm01_address(int rm
)
922 int displacement
= 0;
925 /* Fetch disp8 if no SIB byte */
926 if (!((M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) && (rm
== 4)))
927 displacement
= (s8
) fetch_byte_imm();
929 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
930 /* 32-bit addressing */
933 DECODE_PRINTF2("%d[EAX]", displacement
);
934 return M
.x86
.R_EAX
+ displacement
;
936 DECODE_PRINTF2("%d[ECX]", displacement
);
937 return M
.x86
.R_ECX
+ displacement
;
939 DECODE_PRINTF2("%d[EDX]", displacement
);
940 return M
.x86
.R_EDX
+ displacement
;
942 DECODE_PRINTF2("%d[EBX]", displacement
);
943 return M
.x86
.R_EBX
+ displacement
;
945 sib
= fetch_byte_imm();
946 displacement
= (s8
) fetch_byte_imm();
947 DECODE_PRINTF2("%d", displacement
);
948 return decode_sib_address(sib
, 1) + displacement
;
950 DECODE_PRINTF2("%d[EBP]", displacement
);
951 return M
.x86
.R_EBP
+ displacement
;
953 DECODE_PRINTF2("%d[ESI]", displacement
);
954 return M
.x86
.R_ESI
+ displacement
;
956 DECODE_PRINTF2("%d[EDI]", displacement
);
957 return M
.x86
.R_EDI
+ displacement
;
962 /* 16-bit addressing */
965 DECODE_PRINTF2("%d[BX+SI]", displacement
);
966 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
968 DECODE_PRINTF2("%d[BX+DI]", displacement
);
969 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
971 DECODE_PRINTF2("%d[BP+SI]", displacement
);
972 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
973 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
975 DECODE_PRINTF2("%d[BP+DI]", displacement
);
976 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
977 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
979 DECODE_PRINTF2("%d[SI]", displacement
);
980 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
982 DECODE_PRINTF2("%d[DI]", displacement
);
983 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
985 DECODE_PRINTF2("%d[BP]", displacement
);
986 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
987 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
989 DECODE_PRINTF2("%d[BX]", displacement
);
990 return (M
.x86
.R_BX
+ displacement
) & 0xffff;
994 return 0; /* SHOULD NOT HAPPEN */
997 /****************************************************************************
999 rm - RM value to decode
1002 Offset in memory for the address decoding
1005 Return the offset given by mod=10 addressing. Also enables the
1006 decoding of instructions.
1007 ****************************************************************************/
1009 decode_rm10_address(int rm
)
1011 u32 displacement
= 0;
1014 /* Fetch disp16 if 16-bit addr mode */
1015 if (!(M
.x86
.mode
& SYSMODE_PREFIX_ADDR
))
1016 displacement
= (u16
) fetch_word_imm();
1018 /* Fetch disp32 if no SIB byte */
1020 displacement
= (u32
) fetch_long_imm();
1023 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
1024 /* 32-bit addressing */
1027 DECODE_PRINTF2("%08x[EAX]", displacement
);
1028 return M
.x86
.R_EAX
+ displacement
;
1030 DECODE_PRINTF2("%08x[ECX]", displacement
);
1031 return M
.x86
.R_ECX
+ displacement
;
1033 DECODE_PRINTF2("%08x[EDX]", displacement
);
1034 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1035 return M
.x86
.R_EDX
+ displacement
;
1037 DECODE_PRINTF2("%08x[EBX]", displacement
);
1038 return M
.x86
.R_EBX
+ displacement
;
1040 sib
= fetch_byte_imm();
1041 displacement
= (u32
) fetch_long_imm();
1042 DECODE_PRINTF2("%08x", displacement
);
1043 return decode_sib_address(sib
, 2) + displacement
;
1046 DECODE_PRINTF2("%08x[EBP]", displacement
);
1047 return M
.x86
.R_EBP
+ displacement
;
1049 DECODE_PRINTF2("%08x[ESI]", displacement
);
1050 return M
.x86
.R_ESI
+ displacement
;
1052 DECODE_PRINTF2("%08x[EDI]", displacement
);
1053 return M
.x86
.R_EDI
+ displacement
;
1058 /* 16-bit addressing */
1061 DECODE_PRINTF2("%04x[BX+SI]", displacement
);
1062 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1064 DECODE_PRINTF2("%04x[BX+DI]", displacement
);
1065 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1067 DECODE_PRINTF2("%04x[BP+SI]", displacement
);
1068 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1069 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1071 DECODE_PRINTF2("%04x[BP+DI]", displacement
);
1072 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1073 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1075 DECODE_PRINTF2("%04x[SI]", displacement
);
1076 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
1078 DECODE_PRINTF2("%04x[DI]", displacement
);
1079 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
1081 DECODE_PRINTF2("%04x[BP]", displacement
);
1082 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1083 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
1085 DECODE_PRINTF2("%04x[BX]", displacement
);
1086 return (M
.x86
.R_BX
+ displacement
) & 0xffff;