This is the mail archive of the gas2@sourceware.cygnus.com mailing list for the gas2 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: 16-bit i386 code support in GAS


> From: Ken Raeburn <raeburn@cygnus.com>
> 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  <jrs@world.std.com>

	* 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  <jrs@world.std.com>

	* 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*));