TweetFollow Us on Twitter

Forth Decompiler
Volume Number:1
Issue Number:2
Column Tag:Forth Forum

“A Forth Decompiler”

By Joerg Langowski

“A Forth Decompiler”

Everyone of you Mac Forth users is familiar enough with Forth to know that it is a ‘threaded interpretive’ language. A Forth definition (as you type it into your machine) consists of a string of other, previously defined Forth words, and is compiled as a string of addresses that point to the definitions of these other words.

This makes for a rather fast interpretation of the resulting code. However, some of the very primitive words and those words whose execution is time-critical may also be defined in machine language. MacForth has devised a very elegant way to distinguish between Forth words defined from within Forth and machine code.

Structure of a Forth Definition

The object code of any Forth word, as it is compiled into the object dictionary, starts with at least one 16-bit word that is a meaningful executable 68000 machine language instruction. When the Forth word is executed, the interpreter simply jumps to this address. Forth definitions (colon definitions, constants, variables) now start with one of the 68000 TRAP instructions ($4E4X, where X can be anything from $0 to $F). The corresponding trap vector points to a routine which e.g. in the case of a colon definition gets the next 16-bit word and interprets it as a Forth token (converts it to an address and executes it), or - in the case of a variable - puts the address of the variable on the stack.

If the word is defined completely in machine language, the code is executed until a special JMP instruction transfers control to the next higher level (I’ll describe that later).

At this point I have to confess that I would not have come even this far if it had not been for two excellent routines that I found on a CALL-A.P.P.L.E. public domain disk. One of those - a Forth decompiler - is included below so that you can enjoy hacking into the Forth engine, the other one - a disassembler - was too long to be printed here.

An Example

Admittedly, part of the above sounds a bit dry and theoretical. Lets look at a simple example.

Assume you had defined the word TEST as follows:

: TEST DUP 2* SWAP DROP . ; 

The Forth compiler will then create a list of 16-bit words that looks like:

 $4E4F  (trap for colon definition)
 $0498  (Forth token for DUP    )
 $074E  (   “          “     “   2*     )
 $049C  (   “          “     “   SWAP)
 $00EC  (   “          “     “   DROP )
 $0EBE  (   “          “     “    .     )
 $0060      (   “          “     “  EXIT  )

Interpretation always ends at the EXIT token.

TOKENS

What are those ‘tokens’? They are the starting addresses of the Forth definitions that are offset by a constant that is contained in register A4 (probably to make the object code relocatable). There is a word in MacForth that converts a token to an address, TOKEN>ADDR. The token of a word is extracted from the vocabulary by the Forth word, FIND. Therefore, you will get the starting address of the example above by executing

FIND TEST TOKEN>ADDR .

The address that you’ll see displayed, of course, depends on how much object code you have already in your system. Let’s call this number TESTADDR. Then define the following word:

 :  TEST.DISP  7 0 DO I 2* TESTADDR ( insert your # here) + W@ . LOOP 
;

and execute TEST.DISP; you will see the list of words above.

This way you can decompile any Forth word that you find in the system. The decompiler is somewhat more convenient, of course; if you use the procedure above, you still have to convert the tokens into Forth words. This is done (for one token on the stack) by executing

 NFA ID.

This converts the token (not the pfa, as the Forth 1.1 manual says) into the name field address (NFA) and then displays the name of the word (ID.).

Machine language definitions

What if the definition is direct machine language code? Again, let us look at an example, the word SWAP. FIND SWAP TOKEN>ADDR gives (in my system) $5B60. At this address, however, we find code that does not start with a trap statement; it is a routine that does what we expect:

 202F 0004MOVE.L 4(A7),D0    /move item below top -> D0
 2F57 0004MOVE.L (A7),4(A7) /move top item one down
 2E80   MOVE.L D0,(A7)       /move D0 -> top of stack
 4ED4   JMP (A4)                  
/get next token

We see that indeed the two top stack items are exchanged. The last statement is the end of any machine language Forth definition. This jump to the address in A4 is what I briefly mentioned above. A4 contains the address of a routine that gets and executes the next Forth token from the object code (which A3 points to):

 MOVE (A3)+,D0 
/next object token -> D0
 BMI L1 
/is it neg. get address from token table
 JMP (A4,D0.W) 
/jump to start of definition (token + A4)
L1 MOVE(A4,D0.W),D1
/get address from table
 JMP (A4,D1.W) 
/and jump to start of definition

Hidden definitions

When you decompile (with the program below) the word SELECT.WINDOW, you’ll see something funny. It seems to be a regular Forth colon definition; however, the tokens displayed seem to have no name. Only ??? and the token numbers are displayed. These are tokens whose names have been deleted from the vocabulary, but their corresponding addresses (A4+token) point to valid definitions. The reason why CSI did this is probably to keep the vocabulary short and to make words inaccessible to users whose misuse could have a disasterous effect on the system. Anyway, the word SUBLEVEL in the definitions below will decompile and display any such ‘hidden’ code, if it is a colon definition. It will display nothing for machine code definitions, you have to disassemble them.

SELECT.WINDOW, with this tool, then becomes very clear. Its first level definition looks like:

: SELECT.WINDOW {2142} {1B0E}  ;

where the braces indicate those ‘no-name’ tokens. {2142} merely checks if the pointer on the stack is a valid window pointer, to keep the toolbox routine from crashing; decompile it with SUBLEVEL to see what it does exactly. {1B0E} is a 2-word machine code routine:

 $A91F  
/toolbox trap for SELECT.WINDOW
 JMP (A4) 
/and get next word. That’s all!

Listing 1: Forth decompiler
( DECOMPILER Blocks File -- Version 1.00 )        ( ADG - modif. 110384 
jl ) 
 DECOMP  ( -- )                                                 
Decompiles the definition of the next word in the input stream.  A line 
is displayed for each word in the definition. Each line begins with its 
relative code address in hex.  Next is the name of the word.  Finally, 
if the word has an in-line parameter, it is shown.  If the word is a 
branching word, the value is the target address.  If the parameter is 
a token, its name is shown.  If it is a string, the string is shown in 
double-quotes.  If it is a word or double-word, its hex value is followed 
by its decimal value.                            
#DECOMP in block 8 can also be loaded by those who wish to write a routine 
to pass tokens on the stack to be decompiled. For valid tokens, its output 
is identical to that of DECOMP .
 Written: 07/21/84   By: Alan D. Galumbeck  [70220,200]         
 NO RIGHTS RESERVED    NO RIGHTS RESERVED    NO RIGHTS RESERVED 

BASE @ DECIMAL   VARIABLE HIGH.PFA  16384 MINIMUM.OBJECT  2048 MINIMUM.VOCAB 
        : .DIGITS  ( n1\n2 --  | Types the low-order n2 digits of n1 
)  0 <# DO # LOOP #> TYPE ;          : SPACE.TO  ( n -- | Spaces to column 
n or 2 spaces if past n ) COL @ - 2 MAX SPACES ;               : DISP.WORD 
   ( pfa -- pfa+2 | Display a 16-bit parameter)     
  DUP W@ 4 .DIGITS 31 SPACE.TO DECIMAL DUP <W@ . HEX  DUP W@    
  NFA ?DUP IF 42 SPACE.TO ID. THEN  2+ ;
: DISP.DBL     ( pfa -- pfa+4 | Display a 32-bit parameter )    
  DUP @ DUP 8 .DIGITS 31 SPACE.TO DECIMAL . HEX 4+ ;  
: DISP.STRING  ( pfa -- pfa+len | Display a string parameter )  
  34 EMIT COUNT 2DUP TYPE 34 EMIT + =CELLS ;                    
: DISP.TARGET  ( base.pfa\pfa -- base.pfa\pfa+2 )               
  ( Display a branch target and save if it’s the highest )      
  DUP <W@ OVER + DUP HIGH.PFA @ > IF HIGH.PFA ! ELSE DROP THEN  
  2DUP SWAP - OVER <W@ + . 2+ ;                                 
: DISP.TOKEN   ( pfa -- pfa+2 | Display a token parameter)      
  DUP W@ NFA ?DUP  IF ID.  ELSE DUP W@ 4 .DIGITS  THEN  2+ ;    
: DISP.ADDR  ( pfa -- pfa+4 | Display an address parameter )    
  DUP @ NFA ?DUP  IF ID.  ELSE DUP @ NEXT.PTR + 8 .DIGITS THEN 4+ ;  
  
: SPECIAL.TOKENS ( base.pfa\pfa\token -- [base.pfa\next.pfa] or 
                                         [base.pfa\next.pfa\0] )
  ( Handle in-line parameters and terminating words )           
  CASE  TOKEN.FOR  EXIT       OF        0                  ENDOF
        TOKEN.FOR  (;CODE@)   OF        DISP.TOKEN 0       ENDOF
        TOKEN.FOR  COMPILE    OF        DISP.TOKEN         ENDOF
        TOKEN.FOR  0BRANCH    OF        DISP.TARGET        ENDOF
        TOKEN.FOR  BRANCH     OF        DISP.TARGET        ENDOF
        TOKEN.FOR  (OF)       OF        DISP.TARGET        ENDOF
        TOKEN.FOR  (LOOP)     OF        DISP.TARGET        ENDOF
        TOKEN.FOR  (+LOOP)    OF        DISP.TARGET        ENDOF
        TOKEN.FOR (MENU.SELECTION:) OF  DISP.TARGET        ENDOF
        TOKEN.FOR  ALIT       OF        DISP.ADDR          ENDOF
        TOKEN.FOR  WLIT       OF        DISP.WORD          ENDOF
        TOKEN.FOR  LIT        OF        DISP.DBL           ENDOF
        TOKEN.FOR  (.”)       OF        DISP.STRING        ENDOF
        TOKEN.FOR  ($LIT)     OF        DISP.STRING        ENDOF
        TOKEN.FOR  (ERROR”)   OF        DISP.STRING        ENDOF
        TOKEN.FOR  (ABORT”)   OF        DISP.STRING        ENDOF
        TOKEN.FOR  $ADDR      OF        DISP.STRING        ENDOF
        ( Insert the ones I’ve missed here. )                   
        0                     OF        2 - DISP.TOKEN     ENDOF
  ENDCASE ;  

: DECODE.TOKENS  ( pfa --  | Display the words starting at pfa )
  DUP HIGH.PFA ! DUP                                            
  BEGIN                                                         
    HEX 2DUP SWAP - CR 4 .R 2 SPACES DUP 2+ SWAP W@ DUP NFA ?DUP     
                            
      IF    ID.    ELSE .” ???” drop 0  THEN                         
        
      20 SPACE.TO SPECIAL.TOKENS ?DUP                           
      IF    FALSE  ELSE  DUP HIGH.PFA @ > THEN                       
        
  UNTIL                                                         
  2DROP ;                                                       

: .VALUE  ( n1\n2 --  | Display constants and UA variables )    
  HEX .DIGITS .”  hex  “ DECIMAL . .” decimal )”  ;             
                                                                
: DECODE.VECTOR  ( pfa\vector -- | Display definition type )    
  CASE                                                          
    11 OF .” User Area variable ( Offset = “ W@ DUP 4  .VALUE  ENDOF
    12 OF .” 16 bit constant ( Value = “ <W@ DUP 4 .VALUE  ENDOF
    13 OF .” 32 bit constant ( Value = “ @ DUP 8 .VALUE   ENDOF
    14 OF .” Variable, array, or string” DROP              ENDOF
    15 OF .” Colon definition” DECODE.TOKENS               ENDOF
    .” Unknown code type ( Vector = “ 2 .VALUE .” )”            
  ENDCASE ;                                                     
                                                                 
: CHK.CODE.TYPE  ( token -- [pfa\vector\true] or [false] |      
   Returns false for machine code definitions, true for others )
   TOKEN>ADDR DUP 2+ SWAP W@ DUP 16/ 1252 = 
   IF 15 AND TRUE ELSE 2DROP FALSE THEN ;                     
 ( Note: 1252 is the machine code for a 68000 TRAP instruction  
         divided by 16.  Vector is the low-order four bits of   
         the TRAP instruction. )                                
: sublevel chk.code.type if drop decode.tokens then ;           
                                                               
: DECOMP  ( --  | Decompile the next word in the input stream ) 
  GET.LINE.HEIGHT  GET.TEXTSIZE  BASE @  9 TEXTSIZE  10 LINE.HEIGHT  
                                  
  +FIND CR POCKET COUNT TYPE .”  -- “                           
     IF 
        IF .” IMMEDIATE “ THEN                                  
        CHK.CODE.TYPE IF DECODE.VECTOR ELSE .” Machine code definition” 
THEN                   
     ELSE .” Not in dictionary” THEN                            
  BASE !  TEXTSIZE  LINE.HEIGHT  CR ;                           
                                                                
: #DECOMP ( token --  | Decompile word whose token is supplied )
  BASE @  GET.LINE.HEIGHT  GET.TEXTSIZE  4 PICK DUP             
  9 TEXTSIZE  10 LINE.HEIGHT NFA ?DUP CR                        
     IF DUP ID.  .” -- “ C@ 128 AND                              
        IF .” IMMEDIATE “ THEN                                  
        CHK.CODE.TYPE  IF DECODE.VECTOR  ELSE .” Machine code definition” 
THEN                   
     ELSE HEX 4 .DIGITS .” -- Not a valid token” THEN           
  TEXTSIZE  LINE.HEIGHT  BASE !  DROP  CR ;                     


 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Smultron 9.4 - Easy-to-use, powerful tex...
Smultron 9 is an elegant and powerful text editor that is easy to use. Use it to create or edit any text document. Everything from a web page, a note or a script to any single piece of text or code.... Read more
TextSoap 8.4 - Automate tedious text doc...
TextSoap can automatically remove unwanted characters, fix up messed up carriage returns, and do pretty much anything else that we can think of to text. Save time and effort. Be more productive. Stop... Read more
Merlin Project 4.2.3 - $349.00
Merlin Project is the leading professional project management software for OS X. If you plan complex projects on your Mac, you won’t get far with a simple list of tasks. Good planning raises... Read more
QuarkXPress 13.0.0.0 - Desktop publishin...
QuarkXPress 2017 is the new version that raises the bar for design and productivity. With non-destructive graphics and image editing directly within your layout, you no longer have to choose between... Read more
Path Finder 7.5 - Powerful, award-winnin...
Path Finder makes you a master of file management. Take full control over your file system. Save your time: compare and synchronize folders, view hidden files, use Dual Pane and full keyboard... Read more
Path Finder 7.5 - Powerful, award-winnin...
Path Finder makes you a master of file management. Take full control over your file system. Save your time: compare and synchronize folders, view hidden files, use Dual Pane and full keyboard... Read more
Merlin Project 4.2.3 - $349.00
Merlin Project is the leading professional project management software for OS X. If you plan complex projects on your Mac, you won’t get far with a simple list of tasks. Good planning raises... Read more
TextSoap 8.4 - Automate tedious text doc...
TextSoap can automatically remove unwanted characters, fix up messed up carriage returns, and do pretty much anything else that we can think of to text. Save time and effort. Be more productive. Stop... Read more
Smultron 9.4 - Easy-to-use, powerful tex...
Smultron 9 is an elegant and powerful text editor that is easy to use. Use it to create or edit any text document. Everything from a web page, a note or a script to any single piece of text or code.... Read more
QuarkXPress 13.0.0.0 - Desktop publishin...
QuarkXPress 2017 is the new version that raises the bar for design and productivity. With non-destructive graphics and image editing directly within your layout, you no longer have to choose between... Read more

Latest Forum Discussions

See All

Magikarp Jump splashes onto Android worl...
If you're tired ofPokémon GObut still want something to satisfy your mobilePokémon fix,Magikarp Jumpmay just do the trick. It's out now on Android devices the world over. While it looks like a simple arcade jumper, there's quite a bit more to it... | Read more »
Purrfectly charming open-world RPG Cat Q...
Cat Quest, an expansive open-world RPG from former Koei-Tecmo developers, got a new gameplay trailer today. The video showcases the combat and exploration features of this feline-themed RPG. Cat puns abound as you travel across a large map in a... | Read more »
Jaipur: A Card Game of Duels (Games)
Jaipur: A Card Game of Duels 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: ** WARNING: iPad 2, iPad Mini 1 & iPhone 4S are NOT compatible. ** *** Special Launch Price for a limited... | Read more »
Subdivision Infinity (Games)
Subdivision Infinity 1.03 Device: iOS Universal Category: Games Price: $2.99, Version: 1.03 (iTunes) Description: Launch sale! 40% Off! Subdivision Infinity is an immersive and pulse pounding sci-fi 3D space shooter. https://www.... | Read more »
Clash of Clans' gets a huge new upd...
Clash of Clans just got a massive new update, and that's not hyperbole. The update easily tacks on a whole new game's worth of content to the hit base building game. In the update, that mysterious boat on the edge of the map has been repaired and... | Read more »
Thimbleweed Park officially headed to iO...
Welp, it's official. Thimbleweed Park will be getting a mobile version. After lots of wondering and speculation, the developers confirmed it today. Thimbleweed Park will be available on both iOS and Android sometime in the near future. There's no... | Read more »
Pokémon GO might be getting legendaries...
The long-awaited legendary Pokémon may soon be coming to Pokémon GO at long last. Data miners have already discovered that the legendary birds, Articuno, Moltres, and Zapdos are already in the game, it’s just a matter of time. [Read more] | Read more »
The best deals on the App Store this wee...
If you’ve got the Monday blues we have just the thing to cheer you up. The week is shaping up to be a spectacular one for sales. We’ve got a bunch of well-loved indie games at discounted prices this week along with a few that are a little more... | Read more »
Honor 8 Pro, a great choice for gamers
Honor is making strides to bring its brand to the forefront of mobile gaming with its latest phone, the Honor 8 Pro. The Pro sets itself apart from its predecessor, the Honor 8, with a host of premium updates that boost the device’s graphical and... | Read more »
The 4 best outdoor adventure apps
Now that we're well into the pleasant, warmer months, it's time to start making the most of the great outdoors. Spring and summer are ideal times for a bit of trekking or exploration. You don't have to go it alone, though. There are plenty of... | Read more »

Price Scanner via MacPrices.net

Sale! 15-inch 2.6GHz Silver Touch Bar MacBook...
DataVision has the 15″ 2.6GHz Silver Touch Bar MacBook Pro (MLW72LL/A) on sale for $2199 including free shipping. Their price is $200 off MSRP, and it’s the lowest price available for this model (... Read more
A Kaby Lake Processor Upgrade For The MacBook...
Now they tell me! Well, actually Apple hasn’t said anything official on the subject, but last week Bloomberg News’s Mark Gurman and Alex Webb cited unnamed “people familiar with the matter”... Read more
Kodak’s Camera-First Smartphone EKTRA Launche...
The Eastman Kodak Company and Bullitt Group have announced the availability of a U.S. GSM version of the KODAK EKTRA Smartphone. The U.S. launch coincides with a software update addressing requests... Read more
Apple Launches App Development Curriculum for...
Apple today launched a new app development curriculum designed for students who want to pursue careers in the fast-growing app economy. The curriculum is available as a free download today from Apple... Read more
Check Apple prices on any device with the iTr...
MacPrices is proud to offer readers a free iOS app (iPhones, iPads, & iPod touch) and Android app (Google Play and Amazon App Store) called iTracx, which allows you to glance at today’s lowest... Read more
9.7-inch 2017 iPad available for $298, save $...
Sams Club has 32GB 9.7″ Apple iPads available for $298 for Sams Club members. That’s $21 off MSRP. Order online and choose free local store pickup (if available) or free shipping. Read more
touchbyte Releases PhotoSync 3.2 for iOS With...
Hamburg, Germany based touchbyte has announced the release of PhotoSync 3.2 for iOS, a major upgrade to the versatile and powerful app to transfer, backup and share photos and videos over the air.... Read more
Emerson Adds Touchscreen Display and Apple Ho...
Emerson has announced the next evolution of its nationally recognized smart thermostat. The new Sensi Touch Wi-Fi Thermostat combines proven smarthome technology with a color touchscreen display and... Read more
SurfPro VPN for Mac Protects Data While Offer...
XwaveSoft has announced announce the release and immediate availability of SurfPro VPN 1.0, their secure VPN client for macOS. SurfPro VPN allows Mac users to protect their internet traffic from... Read more
13-inch Touch Bar MacBook Pros on sale for $1...
B&H Photo has 13″ MacBook Pros in stock today for up to $150 off MSRP. Shipping is free, and B&H charges NY & NJ sales tax only: - 13″ 2.9GHz/512GB Touch Bar MacBook Pro Space Gray (... Read more

Jobs Board

Data Engineer - *Apple* Media Products - Ap...
Changing the world is all in a day's work at Apple . If you love innovation, here's your chance to make a career of it. You'll work hard. But the job comes with more Read more
*Apple* Store Leader Program - Apple, Inc (U...
…Summary Learn and grow as you explore the art of leadership at the Apple Store. You'll master our retail business inside and out through training, hands-on Read more
*Apple* Integration Specialist - A3 Solution...
Apple Integration Specialist Contract-To-HireWe are searching for dedicated, well-experienced and energetic individuals for an information technology corporation Read more
Sr. Software Engineer, *Apple* Online Store...
Changing the world is all in a day's work at Apple . If you love innovation, here's your chance to make a career of it. You'll work hard. But the job comes with more Read more
Senior Engineering Project Manager, *Apple*...
Changing the world is all in a day's work at Apple . If you love innovation, here's your chance to make a career of it. You'll work hard. But the job comes with more Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.