Diagnostic tools and debugging

published: 6 May 2025 / updated 6 May 2025

Lire cette page en français

 

Diagnostic tools and debugging

article: 02 juin 2019 / mis à jour 01 nov. 2019


FORTH is a very powerful programming language because it has various tools assistance that can be used in interpretation or compilation.

The stack and digital base monitor

FORTH allows a lot of boldness, but can also make you lose delicate situations. In the case of a compilation that fails, the digital base change, allowed in both compilation and interpretation, can turn against the programmer:

: TEST ( ---)  
    [ HEX ] ASCII A DDUP    \ DDUP don't exist 
    [ DECIMAL ]  
;  

At the time of compilation, the failure suffered at the time of the attempted treatment of the word DDUP will leave the system in a hexadecimal numeric base. If then we try memory accesses by invoking decimal numeric base addresses, we will suffer small inconveniences.

Specific Flash Forth Part

To avoid getting lost, the availability indicator of the FORTH interpreter, marked by 'OK', may be supplemented by additional indications.

decimal  ok<#,ram> 
hex  ok<$,ram> 
bin  ok<%,ram> 
After "ok", we see this: #,ram>. Here, the sign '#' indicates that we are in decimal place. Here are the different signs that appear:

Now, let's stack some whole values:

10  ok<#,ram> 10 
20  ok<#,ram> 10 20 
35  ok<#,ram> 10 20 35 
42  ok<#,ram> 10 20 35 42 

At each value stack, in interpreted mode, these values appear to the right of ok<#,ram>.

The integers on the right are the values at the top of the stack.

This visibility of the parameters placed in the data stack will allow you to test word for word complex procedures before placing them in a definition to compile.

The decompiler

This part is gForth specific

In a conventional compiler, the source code is transformed into object code containing the reference addresses to a library equipping the compiler. To deposit an executable code, we must link the object code. At no time the programmer can not access the executable code contained in its libraries with the only compiler resources.

With gForth, the developer can decompile his routine, but also visualize predefined primitives so understand the operation of its program or FORTH in its entirety.

To compile a word or definition, just type SEE followed by the word to decompile. Example of compilation with gForth:

: C>F ( øC --- øF) \ Conversion Celsius in Fahrenheit
9 5 */ 32 + 
;  ok
see c>f
\ display:
: C>F
  9 5 */ 32 + ; ok

Let's test SEE on a predefined vocabulary word:

see WORDS
: words
  context @ wordlist-words ; ok
see dup
Code dup
( $402EFA )  mov     dword ptr 42A6F8 , ebx  \ $89 $1D $F8 $A6 $42 $0
( $402F00 )  mov     eax , dword ptr [esi]  \ $8B $6
( $402F02 )  sub     esi , # 4  \ $83 $EE $4
( $402F05 )  add     ebx , # 4  \ $83 $C3 $4
( $402F08 )  mov     dword ptr [esi] , eax  \ $89 $6
( $402F0A )  mov     edi , dword ptr FC [ebx]  \ $8B $7B $FC
( $402F0D )  jmp     4014A4  \ $E9 $92 $E5 $FF $FF
end-code
 ok

Here we have just decompile words then dup. We finds that words is written in FORTH, while words is written in assembly language... The gForth decompiler is also a disassembler!

Memory DUMP

Sometimes it is desirable to be able to see the values that are in memory. The word dump accepts two parameters: the starting address of the "dump" memory and the number of bytes to view. On gForth:

' c>f 32 dump
7FA843D8: A6 14 40 00  00 00 00 00 - 63 FA 9A 7F  09 00 00 00  ..@.....c.......
7FA843E8: 76 FA 9A 7F  05 00 00 00 - EC 20 40 00  90 FA 9A 7F  v........ @.....
 ok

We had compiled the word c>f. By doing ' c>f we point on the field code field and it is asked to see 32 bytes. It does not serve rigorously nothing, it's just for the example...

On Flash Forth:

' c>f 32 dump
12806 :08 149 242 239 226 04 255 255 255 255 255 255 255 255 255 255 ................
12822 :255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 ................ 
ok<#,ram>

Ah damn. The result is in decimal. Let's resume in hexadecimal:

hex  ok<$,ram>
' c>f 32 dump
3206 :08 95 f2 ef e2 04 ff ff ff ff ff ff ff ff ff ff ................
3216 :ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
3226 :ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
ok<$,ram>

Well, after, must decipher the hexadecimal numbers...