papierkorb:4th_lesson_3
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| papierkorb:4th_lesson_3 [2025-08-16 19:07] – ↷ Seite von projects:4th_lesson_3 nach papierkorb:4th_lesson_3 verschoben mka | papierkorb:4th_lesson_3 [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | === Lesson 3 === | ||
| - | < | ||
| - | \ | ||
| - | \ The Forth Course | ||
| - | \ by Richard E. Haskell | ||
| - | \ Dept. of Computer Science and Engineering | ||
| - | \ Oakland University, Rochester, MI 48309 | ||
| - | comment: | ||
| - | |||
| - | |||
| - | |||
| - | Lesson 3 | ||
| - | |||
| - | HOW FORTH WORKS | ||
| - | |||
| - | |||
| - | 3.1 VARIABLES | ||
| - | |||
| - | 3.2 MORE ABOUT VARIABLES -- FETCH AND STORE 3-3 | ||
| - | |||
| - | 3.3 CONSTANTS | ||
| - | |||
| - | 3.4 THE FORTH COLON WORD : 3-6 | ||
| - | |||
| - | 3.5 ARRAYS | ||
| - | |||
| - | 3.6 THE RETURN STACK 3-8 | ||
| - | |||
| - | 3.7 CODE WORDS 3-9 | ||
| - | |||
| - | 3.8 THE FORTH DICTIONARY | ||
| - | |||
| - | 3.9 TABLES | ||
| - | |||
| - | 3.10 CHARACTER OR BYTE DATA 3-12 | ||
| - | |||
| - | 3-11 FINDING DICTIONARY ADDRESSES | ||
| - | |||
| - | 3-12 THE NAME FIELD 3-14 | ||
| - | |||
| - | 3-13 OPERATION OF THE F-PC INNER INTERPRETER | ||
| - | |||
| - | EXERCISES | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.1 VARIABLES | ||
| - | |||
| - | The Forth word VARIABLE is a defining word used to define | ||
| - | variable names. | ||
| - | |||
| - | VARIABLE my.name | ||
| - | |||
| - | then Forth will create a new dictionary entry called my.name. | ||
| - | All dictionary entries have the same general form, consisting of | ||
| - | a header (made up of a view field, a name field and a link field) | ||
| - | and a body (made up of a code field and a parameter field). | ||
| - | F-PC the header and the body are physically stored in separate | ||
| - | segments. | ||
| - | |||
| - | (In the 8086/ | ||
| - | 64 Kbyte segments. | ||
| - | segment address, seg, and a 16-bit offset address, off. The total | ||
| - | address is written as seg: | ||
| - | any 16-byte boundary, called a paragraph. | ||
| - | any byte in memory, one has to specify both a segment address and | ||
| - | an offset address.) | ||
| - | |||
| - | For the word MY.NAME the dictionary entry will look like this | ||
| - | |||
| - | HEADER | ||
| - | view field address ---> | ||
| - | | ||
| - | link field address ---> | ||
| - | | ||
| - | name field address ---> | ||
| - | | Y . | | ||
| - | | N A | | ||
| - | | M E | | ||
| - | | ||
| - | pointer to CFA -------> | ||
| - | | ||
| - | Head Segment YSEG | | ||
| - | | | ||
| - | BODY | ||
| - | code field address ---> | ||
| - | | ||
| - | | ||
| - | | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | The view field contains a character count equal to the offset | ||
| - | address of the beginning of the colon definition within the file. | ||
| - | It is used to locate the colon definition when you ask to VIEW | ||
| - | the definition of a word. | ||
| - | |||
| - | The link field contains a pointer to the LFA of a previously | ||
| - | defined word. | ||
| - | |||
| - | The name field contains the name, beginning with the character | ||
| - | count and followed by 1-31 characters. | ||
| - | |||
| - | The pointer to CFA contains the offset address of the CFA in the | ||
| - | code segment. | ||
| - | ?CS:. | ||
| - | |||
| - | The code field contains code that will be executed when the name | ||
| - | in the name field is interpreted. | ||
| - | code and is used by F-PC. Many Forths use indirect threaded code | ||
| - | in which the code field contains a pointer to the code that is | ||
| - | executed. | ||
| - | corresponding to the instruction CALL >NEXT where >NEXT is the F-PC | ||
| - | inner interpreter to be described later in this lesson. | ||
| - | instruction automatically puts the address of the next instruction | ||
| - | on the stack. | ||
| - | at all but rather the parameter field address. | ||
| - | |||
| - | The parameter field contains different things for different kinds | ||
| - | of words. | ||
| - | 16-bit value of the variable. | ||
| - | in the parameter field when a VARIABLE is defined. | ||
| - | |||
| - | When you type the name of a VARIABLE the CALL >NEXT instruction in | ||
| - | the code field will be exectuted which has the effect of leaving | ||
| - | the parameter field address on the stack. | ||
| - | my.name . | ||
| - | the PFA of my.name will be printed. | ||
| - | |||
| - | |||
| - | 3.2 MORE ABOUT VARIABLES -- FETCH AND STORE | ||
| - | |||
| - | Forth words: | ||
| - | |||
| - | ! ( n addr -- ) ( " | ||
| - | stores the value of n at addr | ||
| - | |||
| - | 6 my.name ! | ||
| - | |||
| - | will store the value 6 at the PFA of my.name. | ||
| - | |||
| - | @ ( addr -- n ) ( " | ||
| - | reads the value at addr and puts it on the stack. | ||
| - | |||
| - | my.name @ . | ||
| - | |||
| - | will print the value of my.name. | ||
| - | |||
| - | Stack variables | ||
| - | |||
| - | The system variable SP0 contains the value of the stack pointer | ||
| - | for an empty stack. | ||
| - | |||
| - | SP0 @ | ||
| - | |||
| - | will return the address of the stack pointer when nothing is on | ||
| - | the stack. | ||
| - | |||
| - | The Forth word SP@ returns the address of the last item pushed on | ||
| - | the stack. | ||
| - | |||
| - | The Forth word DEPTH returns the number of items on the stack. | ||
| - | It is defined as follows: | ||
| - | |||
| - | : DEPTH ( -- n ) | ||
| - | SP@ SP0 @ | ||
| - | SWAP - 2/ ; | ||
| - | |||
| - | Note that since each element on the stack is a word that contains | ||
| - | two bytes, the number of bytes on the stack must be divided by 2 | ||
| - | to give the number of words on the stack. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.3 CONSTANTS | ||
| - | |||
| - | The Forth word CONSTANT is a defining word that lets you define | ||
| - | constants. | ||
| - | |||
| - | 25 CONSTANT quarter | ||
| - | |||
| - | the name quarter will be entered into the dictionary as follows: | ||
| - | |||
| - | ________ | ||
| - | VFA | VIEW | | ||
| - | |------| | ||
| - | LFA | LINK | | ||
| - | |------| | ||
| - | NFA | 7 Q | | ||
| - | | U A | | ||
| - | | R T | | ||
| - | | E R | | ||
| - | |------| | ||
| - | | ^CFA | -------| | ||
| - | |------| | ||
| - | Head Segment YSEG | | ||
| - | | | ||
| - | ________ | ||
| - | CFA | CODE | <------| | ||
| - | |------| | ||
| - | PFA | 25 | | ||
| - | |------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | The code field contains the three bytes corresponding to the | ||
| - | instruction CALL DOCONSTANT. | ||
| - | PFA from the stack (where it was put by the CALL instruction) | ||
| - | and then pushes on the stack the value stored at the PFA. Thus, | ||
| - | if you type | ||
| - | |||
| - | 25 CONSTANT quarter | ||
| - | |||
| - | and then type | ||
| - | |||
| - | quarter . | ||
| - | |||
| - | the value 25 will be printed. | ||
| - | |||
| - | NOTE: The value stored in CONSTANTs are 16-bit signed numbers. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.4 THE FORTH COLON WORD : | ||
| - | |||
| - | The Forth word : (" | ||
| - | define new Forth words. | ||
| - | |||
| - | : squared | ||
| - | |||
| - | the colon word : is executed. | ||
| - | squared as a dictionary entry that looks like this: | ||
| - | |||
| - | |||
| - | ________ | ||
| - | VFA | VIEW | | ||
| - | |------| | ||
| - | LFA | LINK | | ||
| - | |------| | ||
| - | NFA | 7 S | | ||
| - | | Q U | | ||
| - | | A R | | ||
| - | | E D | | | ||
| - | |------| | ||
| - | | ^CFA | -------| | ||
| - | |------| | ||
| - | Head Segment YSEG | ||
| - | | | | ||
| - | ________ | ||
| - | CFA | CODE | < | ||
| - | |------| | ||
| - | PFA | LSO | --------------| | ||
| - | |------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | |||
| - | The code field contains the three bytes corresponding to the | ||
| - | instruction JMP NEST. The code at NEST is part of the inner | ||
| - | interpreter whose operation will be described later in this lesson. | ||
| - | |||
| - | The parameter field contains a list segment offset, LSO, whose value | ||
| - | is added to the base list segment address contained in the variable | ||
| - | XSEG. The resulting segment address is stored in the register ES | ||
| - | and the list of code field addresses making up the definition of | ||
| - | squared is stored in memory starting at address ES:0. | ||
| - | |||
| - | UNNEST is the address of another routine that is part of the Forth | ||
| - | inner interpreter. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.5 ARRAYS | ||
| - | |||
| - | Suppose you want to create an array that contains five 16-bit values. | ||
| - | If you type | ||
| - | |||
| - | VARIABLE my.array | ||
| - | |||
| - | Forth will create the dictionary entry my.array that contains a | ||
| - | single 16-bit value in its parameter field. | ||
| - | |||
| - | ________ | ||
| - | CFA | CODE | <------| | ||
| - | |------| | ||
| - | PFA | 00 | | ||
| - | |------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | Here we have not bothered to show the head segment associated with | ||
| - | the definition of my.array. | ||
| - | 2 bytes to store the 16-bit value. | ||
| - | |||
| - | The Forth word ALLOT will add n bytes to the dictionary in the code | ||
| - | segment where n is the value on the stack when ALLOT is executed. | ||
| - | Thus, | ||
| - | 8 ALLOT | ||
| - | |||
| - | will add 8 bytes, or 4 words to the dictionary. | ||
| - | part of the dictionary entry my.array will then look like this. | ||
| - | |||
| - | _______________ | ||
| - | CFA | CODE | <------| | ||
| - | |-------------| | ||
| - | PFA | my.array(0) | | ||
| - | |-------------| | ||
| - | PFA + 2 | my.array(1) | | ||
| - | |-------------| | ||
| - | PFA + 4 | my.array(2) | | ||
| - | |-------------| | ||
| - | PFA + 6 | my.array(3) | | ||
| - | |-------------| | ||
| - | PFA + 8 | my.array(4) | | ||
| - | |-------------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | |||
| - | To print the value of my.array(3) you could type | ||
| - | |||
| - | my.array 3 2* + @ . | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.6 THE RETURN STACK | ||
| - | |||
| - | When you type a number it is put on the parameter stack. | ||
| - | the arithmetic operations and words such as DUP, ROT, DROP, SWAP, | ||
| - | and OVER operate on numbers that are on the parameter stack. | ||
| - | |||
| - | Forth also has a second stack called the return stack. | ||
| - | stack is used by the Forth inner interpreter to store the return | ||
| - | address of the next word in a colon definition. | ||
| - | by certain Forth words such as DO. | ||
| - | |||
| - | You can also use the return stack IF YOU ARE CAREFUL. | ||
| - | a number from the parameter stack to the return stack temporarily | ||
| - | if you are sure to move it back before the end of a colon definition. | ||
| - | Otherwise, the proper return address will not be on top of the return | ||
| - | stack, and the inner interpreter will not be able to find its way | ||
| - | back to the next word to execute. | ||
| - | |||
| - | The following Forth words use the return stack, R: | ||
| - | |||
| - | >R ( n -- ) ( " | ||
| - | pops the top element of the parameter stack | ||
| - | and pushes it onto the return stack. | ||
| - | |||
| - | Ex. 3 >R | ||
| - | moves 3 to the top of the return stack and | ||
| - | | ||
| - | |||
| - | R> ( -- n ) ( " | ||
| - | pops the top element of the return stack | ||
| - | and pushes it onto the parameter stack. | ||
| - | |||
| - | R@ ( -- n ) ( " | ||
| - | copies the top element of the return stack | ||
| - | to the top of the parameter stack. | ||
| - | |||
| - | |||
| - | Here is a possible definition of ROT: | ||
| - | |||
| - | : ROT ( n1 n2 n3 -- n2 n3 n1 ) | ||
| - | >R \ n1 n2 | ||
| - | SWAP \ n2 n1 | ||
| - | R> \ n2 n1 n3 | ||
| - | SWAP ; \ n2 n3 n1 | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.7 CODE WORDS | ||
| - | |||
| - | Code words are Forth words that are defined in terms of 8086 | ||
| - | machine code rather than in terms of other Forth words. | ||
| - | course, eventually some real 8086 machine code must be executed! | ||
| - | The inner interpreter is written in machine code. In addition, | ||
| - | many of the F-PC Forth words are written in machine code to | ||
| - | maximize their speed of operation. | ||
| - | how you can write your own Forth code words. | ||
| - | |||
| - | Since F-PC uses direct-threading, | ||
| - | is stored directly at the CFA in the code segment. | ||
| - | examples of how some F-PC primatives are defined. | ||
| - | the header of the word is stored in the head segment in the same | ||
| - | way as described previously for VARIABLES, CONSTANTS, and colon | ||
| - | definitions. | ||
| - | DUP | ||
| - | _______________ | ||
| - | CFA | POP AX | <------| | ||
| - | |-------------| | ||
| - | | PUSH AX | | ||
| - | |-------------| | ||
| - | | PUSH AX | | ||
| - | |-------------| | ||
| - | | JMP > | ||
| - | |-------------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | |||
| - | SWAP | ||
| - | _______________ | ||
| - | CFA | POP DX | <------| | ||
| - | |-------------| | ||
| - | | POP AX | | ||
| - | |-------------| | ||
| - | | PUSH DX | | ||
| - | |-------------| | ||
| - | | PUSH AX | | ||
| - | |-------------| | ||
| - | | JMP > | ||
| - | |-------------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | |||
| - | @ (" | ||
| - | _______________ | ||
| - | CFA | POP BX | <------| | ||
| - | |-------------| | ||
| - | | PUSH [BX] | | ||
| - | |-------------| | ||
| - | | JMP > | ||
| - | |-------------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | |||
| - | |||
| - | 3.8 THE FORTH DICTIONARY | ||
| - | |||
| - | The Forth dictionary consists of a linked list of all words that | ||
| - | have been defined. | ||
| - | colon definitions or code words. | ||
| - | are stored in the head segment and linked by means of the link | ||
| - | field pointers. | ||
| - | code field pointer in the header. | ||
| - | real executable code and therefore must be in the 8086 code segment. | ||
| - | In a colon definition the list of CFA's for each word in the | ||
| - | definition is stored in a separate list segment that is pointed to | ||
| - | by a pointer at the PFA in the code segment. | ||
| - | |||
| - | When you define a new word using the colon definition, the | ||
| - | compilation process consists of storing the word in the dictionary. | ||
| - | F-PC links the name of your word into one of 64 threads using a | ||
| - | hashing scheme to increase the speed at which words can be found when | ||
| - | searching the dictionary. | ||
| - | |||
| - | The next available address in the code segment of the dictionary | ||
| - | is given by HERE. That is, HERE is a Forth word that returns the | ||
| - | next available address on the stack. | ||
| - | pointer, contains this next available dictionary address. | ||
| - | HERE is just | ||
| - | : HERE ( -- n ) | ||
| - | DP @ ; | ||
| - | |||
| - | |||
| - | The outer interpreter is what is being executed when you boot up | ||
| - | a Forth system and the ok prompt is displayed. | ||
| - | word and press < | ||
| - | for the word you typed. | ||
| - | executing the code located at the code field address. | ||
| - | find the word, it executes a word called NUMBER that tries to convert | ||
| - | your word to a valid number. | ||
| - | of the number on the stack; otherwise, it displays the <- What? | ||
| - | message that tells you that is doesn' | ||
| - | |||
| - | We will take a closer look at the operation of the inner interpreter | ||
| - | in Section 3.13. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.9 TABLES | ||
| - | |||
| - | A table is like a constant array. | ||
| - | then fill the values of the array using the ! store word. | ||
| - | |||
| - | Another way to create a table is to use the Forth word CREATE | ||
| - | which works the same way as VARIABLE except that no space is | ||
| - | reserved in the parameter field. | ||
| - | |||
| - | CREATE table | ||
| - | |||
| - | you will create the following dictionary entry. | ||
| - | |||
| - | table | ||
| - | ________ | ||
| - | CFA | CODE | <------| | ||
| - | |------| | ||
| - | PFA <---- HERE | ||
| - | |||
| - | Code Segment ?CS: | ||
| - | |||
| - | As with the case of a VARIABLE the code field contains the three bytes | ||
| - | corresponding to the instruction CALL >NEXT where >NEXT is the F-PC | ||
| - | inner interpreter. | ||
| - | field address on the stack when the word table is called. | ||
| - | |||
| - | At this point the dictionary pointer, DP, contains the value of the | ||
| - | PFA of table. | ||
| - | stack at the location pointed to by the dictionary pointer; that is, | ||
| - | at the next available location in the dictionary. | ||
| - | type | ||
| - | CREATE table 5 , 8 , 23 , | ||
| - | |||
| - | the following dictionary entry will be created: | ||
| - | |||
| - | table | ||
| - | ________ | ||
| - | CFA | CODE | <------| | ||
| - | |------| | ||
| - | PFA | | ||
| - | |------| | ||
| - | | | ||
| - | |------| | ||
| - | | 23 | 2 | ||
| - | |------| | ||
| - | Code Segment ?CS: | ||
| - | |||
| - | You could now define a new word called @table as follows: | ||
| - | |||
| - | : @table | ||
| - | 2* table \ 2*ix pfa | ||
| - | + @ ; \ @(pfa + 2*ix) | ||
| - | |||
| - | For example, | ||
| - | will return 23 to the top of the stack. | ||
| - | |||
| - | 3.10 CHARACTER OR BYTE DATA | ||
| - | |||
| - | Character (ASCII) data can be stored in one byte. Data can be | ||
| - | stored and retieved from single bytes using the following Forth | ||
| - | words: | ||
| - | |||
| - | C, ( c -- ) (" | ||
| - | Store least significant byte (LSB) of value on top of | ||
| - | the stack at HERE (next available location in the | ||
| - | dictionary). | ||
| - | |||
| - | C! ( c addr -- ) | ||
| - | Store LSB of value on top of the stack at addr. | ||
| - | |||
| - | C@ ( addr -- c ) | ||
| - | Fetch the byte at addr. Leave as LSB on stack. | ||
| - | |||
| - | |||
| - | You can create a table containing byte values rather than word | ||
| - | values by typing | ||
| - | |||
| - | CREATE table 5 C, 8 C, 23 C, | ||
| - | |||
| - | You can then define a word called C@table as follows: | ||
| - | |||
| - | : C@table | ||
| - | table + C@ ; | ||
| - | |||
| - | 2 C@table will then return 23 to the top of the stack. | ||
| - | |||
| - | Note the difference between C@table and @table defined in | ||
| - | Section 3.9. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.11 FINDING DICTIONARY ADDRESSES | ||
| - | |||
| - | The following words can be used to locate and examine Forth | ||
| - | dictionary entries: | ||
| - | |||
| - | ' | ||
| - | The statement | ||
| - | will leave the CFA of table on the stack. | ||
| - | |||
| - | > | ||
| - | Converts the code field address, CFA, (in the code segment) | ||
| - | to the name field address, NFA, (in the head segment). | ||
| - | |||
| - | > | ||
| - | Converts the code field address, CFA, (in the code segment) | ||
| - | to the link field address, LFA, (in the head segment). | ||
| - | |||
| - | > | ||
| - | Converts the code field address, CFA, (in the code segment) | ||
| - | to the parameter field address, PFA, (in the code segment). | ||
| - | |||
| - | You can go to the code field address by using | ||
| - | |||
| - | BODY> | ||
| - | NAME> | ||
| - | LINK> | ||
| - | |||
| - | You can also go from NAME to LINK and from LINK to NAME using | ||
| - | |||
| - | N> | ||
| - | L> | ||
| - | |||
| - | The Forth word HEX will change the base used to print out values to | ||
| - | hexadecimal. | ||
| - | You can change to any base by storing the value of the base in the | ||
| - | variable BASE. For example, the definition of HEX is | ||
| - | |||
| - | : HEX 16 BASE ! ; | ||
| - | |||
| - | Note that the base must be DECIMAL when this definition of HEX is | ||
| - | loaded. | ||
| - | |||
| - | The Forth word U. prints the top value on the stack as an unsigned | ||
| - | number between 0 and 65535, or if in the HEX mode, between 0000 and | ||
| - | FFFF. As an example, to print the hex address of the name field of | ||
| - | the word OVER type | ||
| - | |||
| - | HEX ' OVER >NAME U. DECIMAL | ||
| - | |||
| - | The Forth word LDUMP ( seg off #bytes -- ) can be used to get a | ||
| - | hex dump of #bytes of memory starting at address seg:off. | ||
| - | For example, type | ||
| - | YSEG @ ' OVER >NAME 20 LDUMP | ||
| - | |||
| - | and see if you can see the name field of OVER. | ||
| - | |||
| - | 3.12 THE NAME FIELD | ||
| - | |||
| - | When you define a new word such as TEST1 using a colon definition | ||
| - | the following name field is created: | ||
| - | |||
| - | Precedence bit ----| |--- Smudge bit Hex value | ||
| - | | ||
| - | | ||
| - | NFA | 1 | 0 | 0 | Name char count = 5 | 85 | ||
| - | | ||
| - | | 0 | Character #1 T = 54H (hex) | 54 | ||
| - | | ||
| - | | 0 | Character #2 E = 45H | ||
| - | | ||
| - | | 0 | Character #3 S = 53H | ||
| - | | ||
| - | | 0 | Character #4 T = 54H | ||
| - | | ||
| - | | 1 | Character #5 1 = 31H | ||
| - | | ||
| - | |||
| - | |||
| - | If the precedence bit is set, the word will be executed immediately. | ||
| - | Immediate words will be discussed in Lesson 9. | ||
| - | |||
| - | If the smudge bit is set, the word will not be able to be found in | ||
| - | a dictionary search. | ||
| - | being compiled. | ||
| - | |||
| - | Type in the following dummy colon definition: | ||
| - | |||
| - | : TEST1 ; | ||
| - | |||
| - | Then examine the name field by typing | ||
| - | |||
| - | YSEG @ ' TEST1 >NAME 10 LDUMP | ||
| - | |||
| - | The six hex values shown in the figure above should be displayed. | ||
| - | |||
| - | Note that the most significant bit is set to 1 in the first and last | ||
| - | byte in the name field. | ||
| - | stored in the name field is the value stored in the variable WIDTH. | ||
| - | For example, | ||
| - | 10 WIDTH ! | ||
| - | |||
| - | will cause a maximum of 10 characters to be stored in the name field. | ||
| - | F-PC sets the default value of WIDTH to 31 -- its maximum possible | ||
| - | value. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 3.13 OPERATION OF THE F-PC INNER INTERPRETER | ||
| - | |||
| - | The following diagram illustates the operation of the F-PC inner | ||
| - | interpreter. | ||
| - | |||
| - | cubed | ||
| - | ________ | ||
| - | CFA | CODE | <------| | ||
| - | |------| | ||
| - | PFA | LSO | -------- +XSEG -------> | ||
| - | |------| | ||
| - | Code Segment ?CS: |< | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | |------| | ||
| - | PFA | LSO | -------- +XSEG -------> | ||
| - | |------| | ||
| - | Code Segment ?CS: | ||
| - | |------| | ||
| - | |UNNEST| | ||
| - | |------| | ||
| - | List Segment XSEG | ||
| - | |||
| - | |||
| - | |||
| - | > | ||
| - | JMP | ||
| - | |||
| - | NEST XCHG BP,SP \ Push IP = ES:SI | ||
| - | PUSH ES \ on the return stack | ||
| - | PUSH SI | ||
| - | XCHG BP,SP | ||
| - | MOV | ||
| - | MOV | ||
| - | ADD | ||
| - | MOV | ||
| - | SUB | ||
| - | JMP > | ||
| - | |||
| - | UNNEST | ||
| - | POP | ||
| - | POP ES | ||
| - | XCHG BP,SP | ||
| - | JMP > | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | The inner interpreter contains the three routines >NEXT, NEST, and | ||
| - | UNNEST. | ||
| - | memory location in the list segment containing the code field address | ||
| - | of the next word to be executed. | ||
| - | is made up of the two registers ES: | ||
| - | the CFA of squared in the definition of cubed as shown in the | ||
| - | previous figure. | ||
| - | address register, W, (which is AX in F-PC) increments IP (SI) by 2 | ||
| - | so that it will point to the next word (*) in the current definition, | ||
| - | and then executes the code at the CFA in W. | ||
| - | |||
| - | If this is a colon definition as it is in this case then the code | ||
| - | at the CFA is a jump to the routine NEST. As shown above NEST will | ||
| - | push IP (both ES and SI) on the return stack so that the program can | ||
| - | later find its way back to the next word in cubed when UNNEST is | ||
| - | executed. | ||
| - | squared, adds it to the base list segment address in XSEG and stores | ||
| - | this value in ES. It then sets SI to zero so that the new IP is | ||
| - | given by ES:0, which points to the first word in the definition of | ||
| - | squared. | ||
| - | time executing the first word in squared, namely, DUP. | ||
| - | |||
| - | Since DUP is a code word, its actual machine code is located at its | ||
| - | CFA. This code will therefore be executed when >NEXT is executed. | ||
| - | The last instruction in the definition of DUP is another jump to | ||
| - | > | ||
| - | CFA of *. Again this is a code word which will be executed and then | ||
| - | jump to >NEXT again. | ||
| - | |||
| - | The last word in a colon definition is UNNEST. | ||
| - | added to the list segment in the dictionary when the semi-colon in a | ||
| - | colon definition is executed. | ||
| - | machine code shown above which pops IP (SI and ES) from the return | ||
| - | stack and then jumps to > | ||
| - | stack by NEST when squared was executed, it will point to the word | ||
| - | following squared in the definition of cubed. | ||
| - | which is the next word to be executed. | ||
| - | |||
| - | This is how Forth works. | ||
| - | CFA's in the list segment. | ||
| - | another colon definition, the IP is incremented and pushed on the | ||
| - | stack and then changed to point to the first CFA in the definition | ||
| - | of the new word to be executed. | ||
| - | of a code word, then the actual machine code located at the CFA is | ||
| - | executed. | ||
| - | execution of each word. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | EXERCISE 3.1 | ||
| - | |||
| - | Define the colon words | ||
| - | |||
| - | : squared | ||
| - | |||
| - | and | ||
| - | : cubed DUP squared * ; | ||
| - | |||
| - | Use the F-PC words ' (" | ||
| - | LDUMP (seg off #bytes -- ) to answer the following questions: | ||
| - | |||
| - | 1) What is code segment address ?CS:? | ||
| - | |||
| - | 2) What is the head segment address stored in YSEG? | ||
| - | |||
| - | 3) What is the list segment address stored in XSEG? | ||
| - | |||
| - | 4) What is the CFA of squared? | ||
| - | |||
| - | 5) What is the LFA of squared? | ||
| - | |||
| - | 6) What is the NFA of squared? | ||
| - | |||
| - | 7) What is the PFA of squared? | ||
| - | |||
| - | 8) What is the CFA of cubed? | ||
| - | |||
| - | 9) What is the LFA of cubed? | ||
| - | |||
| - | 10) What is the NFA of cubed? | ||
| - | |||
| - | 11) What is the PFA of cubed? | ||
| - | |||
| - | 12) Draw a picture of the header of squared showing the | ||
| - | hex values in all locations. | ||
| - | in the ^CFA location? | ||
| - | as well as the list segment dictionary entries for the word | ||
| - | | ||
| - | | ||
| - | |||
| - | 13) What is the LFA of the dictionary entry defined just prior to | ||
| - | | ||
| - | |||
| - | 14) What is the address of NEST? | ||
| - | |||
| - | 15) What is the CFA of DUP? | ||
| - | |||
| - | 16) What is the CFA of *? | ||
| - | |||
| - | 17) What is the address of UNNEST? | ||
| - | |||
| - | comment; | ||
| - | |||
| - | |||
| - | </ | ||
papierkorb/4th_lesson_3.1755364027.txt.gz · Zuletzt geändert: 2025-08-16 19:07 von mka