===== DUMP memory algorithm: display content of main memory =====
==== DUMP idea ====
A DUMP utility is a software tool that allows to inspect main memory and display it in a user readable form.
Typically output is composed of several lines that have the structure:
Display bytes starting in memory at a given address in hex (or other radix). Behind them is the ASCII representation of these bytes.
The DUMP utility is normally called ''DUMP'' and is invoked with parameters which specify what memory to inspect, often start address and length.
==== DUMP Implementation ====
One way to implement DUMP is to iterate in a loop line by line through memory. Say you want to display 16 bytes in each line, then this loop will start
at the start address and increment the address by 16 in each loop iteration. (If you want a different number of bytes in each line, adjust accordingly).
When you display memory in a single line you first output the current address and then have two loops that run one after the other iterating both from 0 to 15.
The first loop outputs bytes with two hexadecimal digits (or in decimal, or whatever you intend) and the second loop outputs the individual bytes as ASCII characters.
As some characters might control the output in a special way (so called control character such as 07 bell, 0A linefeed, 0C formfeed) it is wise to just output a period
instead of the actual character, in order to get a well formatted display.
==== Pseudo code for the DUMP implementation ====
Function: dump-line ( address -- )
output address (possibly right aligned)
output ":" and some space
LOOP i from 0 to 15:
output byte in memory at (address+i) as two hexadecimal digits (or in another radix if desired)
output some space
LOOP i from 0 to 15:
output byte in memory at (address+i) as an ASCII character, "." if that character is a control character (byte<32)
Function: dump ( address length -- )
WHILE length is positive:
dump-line at address
increase address by 16
decrease length by 16
==== Minimal Forth implementation of DUMP: ====
You can find a [[https://github.com/Project-Forth-Works/Project-Forth-Works.github.io/blob/main/minimalforth.md|Minimal Forth]] implementation of DUMP in [[en:pfw:dump-minimal_forth.fs|dump-Minimal_Forth.fs]].
You can use it as follows:
ok
Create x 100 allot ok
x 100 dump
03D694: 05 61 6C 6C 6F 74 08 00 DF 14 00 00 C1 00 08 00 .allot..?...?...
03D6A4: 1F 18 00 00 C1 00 08 00 6F 10 00 00 C1 00 08 00 ....?...o...?...
03D6B4: 4F 10 00 00 C2 00 08 00 1F 13 00 00 C2 00 08 00 O...?.......?...
03D6C4: 8F 30 00 00 C2 00 08 00 DF 14 00 00 C2 00 08 00 ?0..?...?...?...
03D6D4: 1F 18 00 00 C2 00 08 00 6F 10 00 00 C2 00 08 00 ....?...o...?...
03D6E4: 4F 10 00 00 C3 00 08 00 8F 30 00 00 C3 00 08 00 O...?...?0..?...
03D6F4: 5F 13 00 00 _... ok
As the original Minimal Forth has no output facility other than ''emit'' and ''.s'' (specifically no number formatting and no ''.'' or ''.r'')
this implementation seems to be over complicated.
We extended Minimal Forth to [[https://github.com/Project-Forth-Works/Project-Forth-Works.github.io/blob/main/minimalforth.md|GenericForth]] to get a
more useful small Forth.
A DUMP utility in **GenericForth** can be found in [[en:pfw:dump-genericforth.f|dump-GenericForth.f]]
This example is factored using the pseudo code description. The character output has been factored into the useful word PEMIT ( char -- ) too.
==== Various DUMP Implementations ====
Other DUMP implementations can be found at the end of this description.
Your system might lack right justified number output or even BASE for printing numbers in other radix systems. The sample implementation in [[en:pfw:twomoredumps.f|twomoredumps.f]] show how to circumvent this.
==== Background information ====
More about the DUMP utility can found at the [[https://en.wikipedia.org/wiki/Hex_dump|Wikipedia page for hexdump]]
Some Forth DUMP implementations display a fixed amount of bytes and leave the updated address on the stack so that
you can invoke DUMP repeatedly to display successive regions of memory.
==== Possible pitfalls with DUMP ====
Some systems have hardware memory protection that is triggered if you access memory outside the reserved area.
The dump utility can do so by trying to show this forbidden memory. Triggered memory protect might stop the current process and
terminate your session. If necessary a suitable test for the validity of used addresses might be reasonable on such systems so that
dump can issue a normal error message (or display dummy data) in theses cases and leave the system / session otherwise intact.
==== Contributions ====
\ Adapted from Z79Forth. Validated against GNU Forth 0.7.3.
: .doubles ( -- ) $10 0 DO
[CHAR] 0 EMIT I 1 .R SPACE
LOOP ;
: .singles ( -- ) $10 0 DO
I 1 .R
LOOP ;
: .header ( -- ) 1 CELLS 2* 1+ SPACES .DOUBLES .SINGLES CR ;
: .addr S>D <# 1 CELLS 2* 0 DO # LOOP #> TYPE SPACE ;
: .data S>D <# # # #> TYPE SPACE ;
: tochar DUP BL $7F WITHIN 0= IF DROP [CHAR] . THEN ;
VARIABLE start \ Base addr. of the interesting area
VARIABLE bytecount \ Number of interesting bytes
CREATE asciib 16 ALLOT \ Buffer for the ASCII character dump
: dump.initvars.prtheader ( baseaddr bytecount -- align16 )
bytecount ! DUP start ! $-10 AND
( baseaddr bytecount ) HEX CR .header ;
: asciidump asciib $10 TYPE ;
: dump.sanitycheck ( baseaddr bytecount -- baseaddr bytecount )
DEPTH 2 < IF ABORT THEN
DUP 0 <= IF ABORT THEN ;
: dump.iskip.bcount ( addr -- skipbytecount )
start @ $-10 AND = IF
start @ $F AND EXIT
THEN 0 ;
: dump ( baseaddr bypecount -- ) dump.sanitycheck
BASE @ >R
dump.initvars.prtheader >R
BEGIN \ R: saved_BASE currentdumpaddr
I $F AND 0= IF \ Beginning of a dump line
I .addr \ Print the base block address
asciib $10 BLANK \ Initialize the ASCI dump area
THEN
I dump.iskip.bcount ?DUP IF
\ Interesting data not reached yet
DUP 3 * SPACES
R> + >R \ Skip the uninteresting part
THEN
I C@ DUP .data
tochar I $F AND asciib + C!
bytecount DUP @ 1- OVER ! \ bytecount
@ 0= IF \ Last dump line
$F I $F AND - 3 * SPACES
asciidump SPACE
R> DROP R> BASE !
EXIT \ We are done here.
THEN
R> 1+ >R
I $F AND 0= IF \ Last column of non-last line
asciidump CR
THEN
AGAIN ;
[[en:pfw:welcome|Back to PFW page]]
~~DISCUSSION~~