[OpenBIOS] r777 - cpu/x86

svn at openbios.org svn at openbios.org
Thu Jan 17 10:17:08 CET 2008


Author: wmb
Date: 2008-01-17 10:17:08 +0100 (Thu, 17 Jan 2008)
New Revision: 777

Modified:
   cpu/x86/assem.fth
   cpu/x86/disassem.fth
Log:
x86 assembler/disassembler - Fixed several bugs in 16-bit mode.


Modified: cpu/x86/assem.fth
===================================================================
--- cpu/x86/assem.fth	2008-01-12 17:22:24 UTC (rev 776)
+++ cpu/x86/assem.fth	2008-01-17 09:17:08 UTC (rev 777)
@@ -119,7 +119,7 @@
 10 2 32REGS    [EAX]   [ECX]   [EDX]   [EBX]  [ESP]   [EBP] [ESI] [EDI]
  3 2 pmREGS     [AX]    [CX]    [DX]
 
- 2 4 pmreg      [SP] 
+ 2 4 32reg      [SP] 
 
  6 3   REGS      ES      CS      SS      DS     FS      GS
  3 4   REGS       #      #)     S#)
@@ -240,7 +240,7 @@
 
 \ Assemble mod-r/m byte and s-i-b byte if necessary
 : SOP,  ( mr rmid mod -- )
-   protected? if
+   16bit? 0=  if
       2 pick  [SIB] =  if			( [SIB] rmid mod )
 	 [ESP] -rot  mod-rm,			( [SIB] ) \ Scaled index mode
 	 drop					( )
@@ -263,11 +263,11 @@
    \ (nonexistent) "<no-displacement> [EBP]" mode.
 
    OVER #) =  IF
-      protected?  if  5  else  6  then
+      16bit?  if  6  else  5  then
       swap 0 mod-rm, DROP  ADR,  EXIT
    THEN  ( disp mr rmid )
 
-   protected? if
+   16bit? 0=  if
       \ Special case for "0 [EBP]" ; use short 0 displacement
       \ instead of [EBP] (there is no [EBP] addressing mode
       \ because that encoding is used for 32-bit displacement.)
@@ -329,6 +329,8 @@
 \ 2MI  define ascii adjust instructions.
 : 2MI   CREATE  C,  DOES>  C@ ASM8,  12 ASM8,  normal  ;
 
+: prefix-0f  h# 0f asm8,  ;
+
 \ 3MI  define branch instructions, with one or two bytes of offset.
 : 3MI	\ conditional branches
    ( op -- )	create  c,  
@@ -337,7 +339,7 @@
       dup small? if			( op disp8 )
 	 swap asm8, asm8,
       else				( op disp )
-	 h# 0f asm8,  swap h# 10 + asm8,
+	 prefix-0f  swap h# 10 + asm8,
 	 real? if  2  else  4  then  -	 adr,
       then
       normal
@@ -345,7 +347,7 @@
 
 \ 4MI  define LDS, LEA, LES instructions.
 : 4MI   CREATE  C,
-   DOES>  C@  dup h# b2 h# b5 between  if h# 0f asm8, then  ASM8,  MEM,
+   DOES>  C@  dup h# b2 h# b5 between  if prefix-0f then  ASM8,  MEM,
       normal  
 ;
 
@@ -455,7 +457,7 @@
    ELSE                               ( dst apf )
       1+ OVER SEG?  IF                ( dst apf' )  \ Segment register
          OVER FS >=  IF		      ( dst apf' )  \ FS or GS
-	    H# 0F ASM8,  3 + C@       ( dst opcode )
+	    prefix-0f  3 + C@         ( dst opcode )
             SWAP GS = IF  10 OR  THEN ( opcode' )
 	    ASM8,                     ( )
          ELSE			      ( dst apf' )  \ CS, DS, ES, or SS
@@ -528,7 +530,7 @@
 2 1 15mi lgdt   3 1 15mi lidt   2 0 15mi lldt  3 0 15mi ltr
 
 \ LSS, LFS, LGS 
-: 16MI  CREATE  C,  DOES>  C@  H# 0F ASM8,  ASM8,  MEM,  normal  ;
+: 16MI  CREATE  C,  DOES>  C@  prefix-0f  ASM8,  MEM,  normal  ;
 
 \ TEST  bits in dest
 : TEST   (S source dest -- )
@@ -580,7 +582,7 @@
 \ 0x22 for normal->special direction, 0x20 for special->normal direction
 \ or with  0 for CRx, 1 for DRx, 4 for TRx
 : special-mov  ( s d -- )
-   h# 0f asm8,
+   prefix-0f
    [ also forth ]
    dup spec?  if  h# 22  else  swap h# 20  then   ( norm-reg spec-reg opcode )
    over o# 7000 and case
@@ -634,6 +636,10 @@
 ;
 : MOV  (MOV)  normal  ;
 
+\ Use "byte movsx" for the r8 form, "movsx" for the r16 form
+: movsx  ( r/m r -- )  prefix-0f  h# be size,  r/m,  ;
+: movzx  ( r/m r -- )  prefix-0f  h# b6 size,  r/m,  ;
+
 \ Most instructions are defined here. Those mnemonics in
 \ parenthetic comments are defined earlier or not at all.
 
@@ -681,12 +687,12 @@
  9B  1MI WAIT           ( XCHG )  D7  1MI XLAT    30 13MI XOR
  C2 14MI +RET
 
-: invd    ( -- )  h# 0f asm8,  h# 08 asm8,  ;
-: wbinvd  ( -- )  h# 0f asm8,  h# 09 asm8,  ;
-: wrmsr   ( -- )  h# 0f asm8,  h# 30 asm8,  ;
-: rdtsc   ( -- )  h# 0f asm8,  h# 31 asm8,  ;
-: rdmsr   ( -- )  h# 0f asm8,  h# 32 asm8,  ;
-: cpuid   ( -- )  h# 0f asm8,  h# a2 asm8,  ;  \ Arg in %eax, results in ax,bx,dx,cx
+: invd    ( -- )  prefix-0f  h# 08 asm8,  ;
+: wbinvd  ( -- )  prefix-0f  h# 09 asm8,  ;
+: wrmsr   ( -- )  prefix-0f  h# 30 asm8,  ;
+: rdtsc   ( -- )  prefix-0f  h# 31 asm8,  ;
+: rdmsr   ( -- )  prefix-0f  h# 32 asm8,  ;
+: cpuid   ( -- )  prefix-0f  h# a2 asm8,  ;  \ Arg in %eax, results in ax,bx,dx,cx
 
 \ Structured Conditionals
 \ single pass forces fixed size. optimize for small, fast structures:
@@ -720,7 +726,7 @@
 	 drop here 2+ +                 ( addr )
          #) jmp
       else
-	 h# 0f asm8,  h# 10 + asm8,	( offset )
+	 prefix-0f  h# 10 + asm8,	( offset )
 	 real? if 2 else 4 then - adr,
       then
    then
@@ -739,7 +745,7 @@
       dup h# eb =  if
          drop h# e9 asm8,
       else
-         h# 0f asm8,  h# 10 + asm8,
+         prefix-0f  h# 10 + asm8,
       then
       real?  if  0 asm16,  else  0 asm32,  then
    else

Modified: cpu/x86/disassem.fth
===================================================================
--- cpu/x86/disassem.fth	2008-01-12 17:22:24 UTC (rev 776)
+++ cpu/x86/disassem.fth	2008-01-17 09:17:08 UTC (rev 777)
@@ -28,7 +28,7 @@
 true value op32?
 : opv@  ( -- l | w )  op32?  if  op32@  else  op16@  then  ;
 true value ad32?
-: adv@  ( -- l | w )  ad32?  if  op32@  else  op16@ wext  then  ;
+: adv@  ( -- l | w )  ad32?  if  op32@  else  op16@   then  ;
 : dis16  ( -- )  false is op32?  false is ad32?  ;
 : dis32  ( -- )  true  is op32?  true  is ad32?  ;
 \ XXX We should also change the register names e.g. from "eax" to "ax"
@@ -60,7 +60,7 @@
    case
    0  of  " "  exit    endof
    1  of  op8@ bext  dup 0>=  if  ?+  then  endof
-   2  of  ?+ adv@      endof
+   2  of  ?+ adv@ wext     endof
    endcase
    (u.) disp-buf pack  count
 ;
@@ -80,7 +80,7 @@
 ," eax" ," ecx" ," edx" ," ebx" ," esp" ," ebp" ," esi" ," edi"
 end-string-array
 
-: >reg  ( -- adr len )  >regw count  ;
+: >reg  ( -- adr len )  >regw count  op32? 0=  if  1 /string  then  ;
 
 : >greg  ( -- adr len )  wbit  if  >reg  else  >reg8 count  then  ;
 
@@ -101,8 +101,10 @@
       >scale count  $add-text            ( )
    then                                  ( )
 ;
+: .[ " ["  $add-text ;
+: .] " ]"  $add-text ;
 : add-disp  ( sib? reg mod -- )
-   " ["  $add-text               ( sib? reg mod )
+   .[                            ( sib? reg mod )
    2dup 0<>  swap 5 <>  or  if   ( sib? reg mod )   \ D32
       swap >reg $add-text        ( sib? mod )
    else                          ( sib? reg mod )
@@ -110,9 +112,53 @@
    then                          ( sib? mod )
    swap  if  get-scaled  then    ( mod )
    get-disp  $add-text           ( )
-   " ]"  $add-text               ( )
+   .]                            ( )
 ;
 
+: .ea32  ( reg mod -- )
+   >r                                    ( reg r: mod )
+   dup 4 =  if                           ( reg )     \ s-i-b
+      drop  get-op  true  lowbits        ( true reg )
+   else                                  ( reg )     \ displaced
+      false swap                         ( false reg )
+   then                                  ( sib? reg )
+   r> add-disp
+;
+
+string-array modes16
+   ," [bx+si]"
+   ," [bx+di]"
+   ," [bp+si]"
+   ," [bp+di]"
+   ," [si]"
+   ," [di]"
+   ," [bp]"
+   ," [bx]"
+end-string-array
+
+: add-disp16  ( disp -- )
+   h# ffff and  (u.) disp-buf pack count  $add-text
+;
+: +disp16  ( disp -- )
+   dup 0<  if
+      " -" $add-text  negate
+   else
+      " +" $add-text
+   then
+   add-disp16
+;
+
+: .ea16  ( reg mod -- )
+   over 6 =  over 0= and  if             ( reg mod )
+      \ disp16 only, takes the place of the [bp] mode
+      2drop op16@ .[ add-disp16 .] exit
+   then                                  ( reg mod )
+   swap modes16 count $add-text          ( mod )
+   case
+      1 of  op8@  +disp16  endof
+      2 of  op16@ +disp16  endof
+   endcase
+;
 : .ea  ( -- )
    " "  ea-text  place
    lowbits  hibits >r                    ( reg ) ( r: mod )
@@ -120,12 +166,7 @@
       >greg $add-text                    ( )
       r> drop  ea-text ". exit
    then                                  ( reg )
-   dup 4 =  if                           ( reg )     \ s-i-b
-      drop  get-op  true  lowbits        ( true reg )
-   else                                  ( reg )     \ displaced
-      false swap                         ( false reg )
-   then                                  ( sib? reg )
-   r> add-disp
+   r> ad32?  if  .ea32  else  .ea16  then
    ea-text ".
 ;
 : ,ea  ( -- )  .,  .ea  ;
@@ -133,7 +174,7 @@
 
 \ Display formatting
 variable start-column
-: op-col  ( -- )  start-column @  d# 8 +  #out @  -  0 max  spaces  ;
+: op-col  ( -- )  start-column @  d# 9 +  #out @  -  1 max  spaces  ;
 
 string-array >segment
    ," es"  ," cs"  ," ss"  ," ds"  ," fs"  ," gs"
@@ -164,7 +205,7 @@
 : iub   ( -- )  op8@       (.) type  ;
 : iw    ( -- )  op16@ (.) type  ;
 : iv    ( -- )  opv@ (.) type  ;
-: iuv   ( -- )  opv@ (u.) type  ;
+: iuv   ( -- )  adv@ (u.) type  ;
 : ,ib/v ( -- )  .,  wbit  if  opv@  else  op8@  then  (u.) type  ;
 : al/x  ( -- )  wbit  if  ." eax"  else  ." al"  then  ;
 : ,al/x ( -- )  .,  al/x  ;
@@ -186,8 +227,18 @@
    ," s"  ," ns"  ," pe" ," po"  ," l"  ," ge"  ," le"  ," g"
 end-string-array
 
-: jb  ( -- )  op8@ bext  pc @ +  dup branch-target !  showaddr  ;
-: jv  ( -- )  adv@       pc @ +  dup branch-target !  showaddr  ;
+: showbranch  ( offset -- )
+   pc @  ad32?  if  ( offset pc )
+      +                    ( pc' )
+   else                    ( offset pc )
+      lwsplit  -rot        ( pc.high offset pc.low )
+      + h# ffff and        ( pc.high pc.low' )
+      swap wljoin          ( pc' )
+   then                    ( pc' )
+   dup branch-target !  showaddr
+;
+: jb  ( -- )  op8@ bext  showbranch  ;
+: jv  ( -- )  adv@  showbranch  ;
 
 : .jcc  ( -- )  ." j"  low4bits >cond ".  op-col jb  ;
 : ea,g  ( -- )  get-ea  .ea ., gb/v  ;
@@ -404,7 +455,12 @@
    endcase
 ;
 
-: ap  ( -- )  adv@ ." far " op16@ .x  ." :"  showaddr  ;
+: .4x  ( n -- )  push-hex <# u# u# u# u# u#> type pop-base  ;
+: ap  ( -- )
+   adv@ ." far "
+   op16@ push-hex (.) type pop-base
+   ." :"  ad32?  if  showaddr  else  .4x  then
+;
 
 string-array >8line-ops
   ," cwde"  ," cdq"  ," call"  ," wait"  ," pushfd" ," popfd" ," sahf" ," lahf"




More information about the OpenBIOS mailing list