From mboxrd@z Thu Jan 1 00:00:00 1970 From: jrs@world.std.com (Rick Sladkey) To: Ken Raeburn Cc: gas2@cygnus.com Subject: Re: 16-bit i386 code support in GAS Date: Wed, 09 Nov 1994 19:22:00 -0000 Message-id: <941309.222147.jrs@world.std.com> References: <9411091519.AA29119@titanic.nynexst.com> <9411091849.AA00797@cujo.cygnus.com> X-SW-Source: 1994/msg00172.html > From: Ken Raeburn > Subject: Re: 16-bit i386 code support in GAS > Date: Wed, 9 Nov 1994 13:49:07 -0500 > For consistent results, you'd probably want the disassembler to work > in 16-bit mode too. Un(?)fortunately, they use separate copies of > the opcode table, laid out in different formats. Here is i386 16-bit disassembler code which was started by Eric Youngdale and finished by myself. We never got around to submitting it. This code was originally motivated by Wine, the Windows emulator. These changes are relative to an old version of gdb but they patch without problems into the latest sources. ----- Wed Nov 9 22:05:40 1994 Rick Sladkey * bfd/archures.c (bfd_architecture docs): add bfd_mach_i286 and bfd_mach_i386 processors with family. * bfd/bfd-in2.h (bfd_architecture): Likewise. Wed Nov 9 22:05:40 1994 Rick Sladkey * opcodes/i386-dis.c (names_rmw): New vector to decode mod/rm fields unique to 16-bit mode instructions. (machine): New static variable specifying processor. (print_insn_i286_or_i386): Renamed from print_insn_i386. Remove hard-coding of 32-bit code and add special cases for 16-bit mode mod/rm fields. (print_insn_i286, print_insn_i386): New external entry points. * opcodes/disassemble.c (disassembler): Add i286 check. *** gdb-940601/bfd/archures.c-dist Tue Mar 15 10:08:54 1994 --- gdb-940601/bfd/archures.c Sat Jun 4 20:42:25 1994 *************** *** 86,91 **** --- 86,93 ---- . bfd_arch_sparc, {* SPARC *} . bfd_arch_mips, {* MIPS Rxxxx *} . bfd_arch_i386, {* Intel 386 *} + .#define bfd_mach_i286 1 + .#define bfd_mach_i386 2 . bfd_arch_we32k, {* AT&T WE32xxx *} . bfd_arch_tahoe, {* CCI/Harris Tahoe *} . bfd_arch_i860, {* Intel 860 *} *** gdb-940601/bfd/bfd-in2.h-dist Wed Jun 1 17:10:34 1994 --- gdb-940601/bfd/bfd-in2.h Sat Jun 4 20:42:26 1994 *************** *** 959,964 **** --- 959,966 ---- bfd_arch_sparc, /* SPARC */ bfd_arch_mips, /* MIPS Rxxxx */ bfd_arch_i386, /* Intel 386 */ + #define bfd_mach_i286 1 + #define bfd_mach_i386 2 bfd_arch_we32k, /* AT&T WE32xxx */ bfd_arch_tahoe, /* CCI/Harris Tahoe */ bfd_arch_i860, /* Intel 860 */ *** gdb-940601/opcodes/i386-dis.c-dist Wed Mar 30 04:17:53 1994 --- gdb-940601/opcodes/i386-dis.c Sat Jun 4 20:42:26 1994 *************** *** 703,708 **** --- 703,711 ---- static char *names_seg[] = { "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", }; + static char *names_rmw[] = { + "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx", + }; struct dis386 grps[][8] = { /* GRP1b */ *************** *** 950,957 **** } } static int dflag; ! static int aflag; static char op1out[100], op2out[100], op3out[100]; static int op_address[3], op_ad, op_index[3]; --- 953,961 ---- } } + static int machine; static int dflag; ! static int aflag; static char op1out[100], op2out[100], op3out[100]; static int op_address[3], op_ad, op_index[3]; *************** *** 966,974 **** * be used to print the target address if this is a relative jump or call * The function returns the length of this instruction in bytes. */ ! ! int ! print_insn_i386 (pc, info) bfd_vma pc; disassemble_info *info; { --- 970,977 ---- * be used to print the target address if this is a relative jump or call * The function returns the length of this instruction in bytes. */ ! static int ! print_insn_i286_or_i386 (pc, info) bfd_vma pc; disassemble_info *info; { *************** *** 1025,1034 **** return (1); } - /* these would be initialized to 0 if disassembling for 8086 or 286 */ - dflag = 1; - aflag = 1; - if (prefixes & PREFIX_DATA) dflag ^= 1; --- 1028,1033 ---- *************** *** 1140,1145 **** --- 1139,1166 ---- return (codep - inbuf); } + int + print_insn_i286 (pc, info) + bfd_vma pc; + disassemble_info *info; + { + machine = 286; + dflag = 0; + aflag = 0; + return print_insn_i286_or_i386 (pc, info); + } + + int + print_insn_i386 (pc, info) + bfd_vma pc; + disassemble_info *info; + { + machine = 386; + dflag = 1; + aflag = 1; + return print_insn_i286_or_i386 (pc, info, 36); + } + char *float_mem[] = { /* d8 */ "fadds", *************** *** 1539,1544 **** --- 1560,1595 ---- } append_prefix (); + + if (machine == 286) + { + if (mod == 0 && rm == 6) + { + sprintf (scratchbuf, "0x%04.4x", get16 ()); + oappend (scratchbuf); + return 0; + } + + if (mod == 1) + { + FETCH_DATA (the_info, codep + 1); + disp = *(char *)codep++; + } + else if (mod == 2) + disp = get16 (); + else + disp = 0; + if (disp != 0) + { + sprintf (scratchbuf, "0x%x", disp & 0xffff); + oappend (scratchbuf); + } + + sprintf (scratchbuf, "(%s)", names_rmw[rm]); + oappend (scratchbuf); + return 0; + } + if (rm == 4) { havesib = 1; *** gdb-940601/opcodes/disassemble.c-dist Thu Apr 28 19:02:53 1994 --- gdb-940601/opcodes/disassemble.c Sat Jun 4 20:42:26 1994 *************** *** 78,84 **** #endif #ifdef ARCH_i386 case bfd_arch_i386: ! disassemble = print_insn_i386; break; #endif #ifdef ARCH_i960 --- 78,87 ---- #endif #ifdef ARCH_i386 case bfd_arch_i386: ! if (bfd_get_mach(abfd) == bfd_mach_i286) ! disassemble = print_insn_i286; ! else ! disassemble = print_insn_i386; break; #endif #ifdef ARCH_i960 *** gdb-940601/include/dis-asm.h-dist Thu Apr 28 19:07:33 1994 --- gdb-940601/include/dis-asm.h Sat Jun 4 20:42:26 1994 *************** *** 96,101 **** --- 96,102 ---- extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*)); + extern int print_insn_i286 PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));