Fresh IDE . Diff
Not logged in

This repository is a mirror!

The original is located on: https://fresh.flatassembler.net/fossil/repo/fresh
If you want to follow the project, please update your remote-url

Differences From Artifact [997085e001]:

To Artifact [53abddd656]:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

	     The official guide to flat assembler internals


Table of contents
-----------------


Chapter 1  Introduction

	1.1  Source structure
	1.2  Memory organization
	1.3  Core modules

Chapter 2  Interface

	2.1  Interface files
	2.2  Memory allocation
	2.3  Program parameters
	2.4  File operations
	2.5  Environment variables
	2.6  Timestamp
	2.7  Error handling
	2.8  Displaying messages

Chapter 3  Preprocessor

	3.1  Initial state of preprocessor
	3.2  Main preprocessor routine
	3.3  Preprocessing file
	3.4  Tables used by preprocessor
        3.5  Preprocessing line
        3.6  Preprocessing directive handlers



Chapter 1  Introduction
-----------------------

|








|
|
|



|
|
|
|
|
|
|
|



|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

             The official guide to flat assembler internals


Table of contents
-----------------


Chapter 1  Introduction

        1.1  Source structure
        1.2  Memory organization
        1.3  Core modules

Chapter 2  Interface

        2.1  Interface files
        2.2  Memory allocation
        2.3  Program parameters
        2.4  File operations
        2.5  Environment variables
        2.6  Timestamp
        2.7  Error handling
        2.8  Displaying messages

Chapter 3  Preprocessor

        3.1  Initial state of preprocessor
        3.2  Main preprocessor routine
        3.3  Preprocessing file
        3.4  Tables used by preprocessor
        3.5  Preprocessing line
        3.6  Preprocessing directive handlers



Chapter 1  Introduction
-----------------------
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
both case conversion and detecting special characters in source. The table
consists of the 256 bytes, and each corresponds to the character of value the
same as the index of byte in table. The zero byte in table marks that the
corresponding character is one of the special characters (also called
symbol characters), for the other characters the bytes in table are the
values for them after converting to lower case - this will be used for
case insensitive comparisions.
  Then the value of the INCLUDE environment variable is received through the 
interface and stored it in the beginning of main memory block, and the 
[memory_start] variable is updated to point to the first free byte after
this value. This new starting point of main memory block is then used as an
origin of buffer where the preprocessed code will be stored. During the
preprocessing the pointer to the place in this buffer where the data of
preprocessed line will be stored is kept in EDI register, initially it is
equal to the [memory_start] variable. To do the actual preprocessing,
"preprocess_file" routine is called, it needs an EDI to point to the current







|
|







296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
both case conversion and detecting special characters in source. The table
consists of the 256 bytes, and each corresponds to the character of value the
same as the index of byte in table. The zero byte in table marks that the
corresponding character is one of the special characters (also called
symbol characters), for the other characters the bytes in table are the
values for them after converting to lower case - this will be used for
case insensitive comparisions.
  Then the value of the INCLUDE environment variable is received through the
interface and stored it in the beginning of main memory block, and the
[memory_start] variable is updated to point to the first free byte after
this value. This new starting point of main memory block is then used as an
origin of buffer where the preprocessed code will be stored. During the
preprocessing the pointer to the place in this buffer where the data of
preprocessed line will be stored is kept in EDI register, initially it is
equal to the [memory_start] variable. To do the actual preprocessing,
"preprocess_file" routine is called, it needs an EDI to point to the current
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
needed only for the purpose of building the header of each preprocessed line.
This header is 16 bytes long and consists of four double word values, in the
table 3.1 you can see its layout.


   Table 3.1  Header of preprocessed line loaded from source
  /-------------------------------------------------------------------------\
  | Offset | Value							    |
  |========|================================================================|
  |   +0   | pointer to the name of file, from which the line was loaded    |
  |--------|----------------------------------------------------------------|
  |   +4   | line number in bits 0-30, the highest bit zeroed		    |
  |--------|----------------------------------------------------------------|
  |   +8   | offset of line inside the file				    |
  |--------|----------------------------------------------------------------|
  |  +12   | reserved, set to zero					    |
  \-------------------------------------------------------------------------/


  After making the header for line, the "convert_line" routine is called,
which processes one line from source (all bytes from where the ESI points up
to the line break or EOF character) and converts it into data portions that
follow the line header. They are line elements of different types, followed







|



|

|

|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
needed only for the purpose of building the header of each preprocessed line.
This header is 16 bytes long and consists of four double word values, in the
table 3.1 you can see its layout.


   Table 3.1  Header of preprocessed line loaded from source
  /-------------------------------------------------------------------------\
  | Offset | Value                                                          |
  |========|================================================================|
  |   +0   | pointer to the name of file, from which the line was loaded    |
  |--------|----------------------------------------------------------------|
  |   +4   | line number in bits 0-30, the highest bit zeroed               |
  |--------|----------------------------------------------------------------|
  |   +8   | offset of line inside the file                                 |
  |--------|----------------------------------------------------------------|
  |  +12   | reserved, set to zero                                          |
  \-------------------------------------------------------------------------/


  After making the header for line, the "convert_line" routine is called,
which processes one line from source (all bytes from where the ESI points up
to the line break or EOF character) and converts it into data portions that
follow the line header. They are line elements of different types, followed
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    mov ax,4

preprocessor will convert it into the chain of bytes, shown here with their
hexadecimal values (characters corresponding to some of those values are
placed below the hexadecimal codes):

    1A 03 6D 6F 76 1A 02 61 78 2C 1A 01 34 00
	  m  o	v	 a  x  ,	4

  The last type of element that can be found in preprocessed line is the
quoted text. This element is created from chain of any bytes other than
line breaks that are placed between the single or double quotes in the
original text. First byte of such element is always 22h, it is followed
by double word which specifies the number of bytes that follow, and the
value of quoted text comes next. For example, this line from source:

    mov eax,'ABCD'

will be converted into (the notation used is the same as in previous sample):

    1A 03 6D 6F 76 1A 03 65 61 78 2C 22 04 00 00 00 41 42 43 44 00
	  m  o	v	 e  a  x  ,		    A  B  C  D

This data defines two symbols followed by symbol character, quoted text and
zero byte that marks end of line.
  There is also a special case of symbol with first byte having the value 3Bh
instead of 1Ah, such symbol means that all the line elements that follow,
including this one, have already been interpreted by preprocessor and should
be ignored by later modules. Such symbol cannot occur in the data created by







|













|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    mov ax,4

preprocessor will convert it into the chain of bytes, shown here with their
hexadecimal values (characters corresponding to some of those values are
placed below the hexadecimal codes):

    1A 03 6D 6F 76 1A 02 61 78 2C 1A 01 34 00
          m  o  v        a  x  ,        4

  The last type of element that can be found in preprocessed line is the
quoted text. This element is created from chain of any bytes other than
line breaks that are placed between the single or double quotes in the
original text. First byte of such element is always 22h, it is followed
by double word which specifies the number of bytes that follow, and the
value of quoted text comes next. For example, this line from source:

    mov eax,'ABCD'

will be converted into (the notation used is the same as in previous sample):

    1A 03 6D 6F 76 1A 03 65 61 78 2C 22 04 00 00 00 41 42 43 44 00
          m  o  v        e  a  x  ,                 A  B  C  D

This data defines two symbols followed by symbol character, quoted text and
zero byte that marks end of line.
  There is also a special case of symbol with first byte having the value 3Bh
instead of 1Ah, such symbol means that all the line elements that follow,
including this one, have already been interpreted by preprocessor and should
be ignored by later modules. Such symbol cannot occur in the data created by
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
of prioritized constants - to detect such definition preprocessor checks
whether the first two data portions are symbols, and whether the second symbol
is the word "fix". If such situation is detected, preprocessor jumps to the
"define_fix_constant" handler. Otherwise it calls the "process_fix_constants"
routine, which checks the line for occurences of prioritized symbolic constants
and if any are found, it replaces them with their values.
  In case when the line that is preprocessed is not line converted directly
from source, but the line generated by macroinstruction, the prioritized 
constants and their definitions are not detected and processed in such line
(since they were already processed in the original source line that generated
this new one). Instead, it calls the "process_macro_operators" routine, which
does some processing specific to lines generated by macroinstruction - it will
be explained in details later.
  After this initial processing is finished, the main check for directives and 
macroinstructions comes. If the first element of line is the symbol, preprocessor
checks whether is it a directive with the "get_symbol" routine. This procedure 
needs ESI to point to the data of symbol, ECX to contain the length of symbol 
and EDI to point to the table of symbols that have to be recognized. Each entry 
in that table begins with one byte containing the length of symbol, then this 
amount of bytes containing the symbol itself and then one 16-bit word containing 
identifier of the symbol. In case of directives the identifier is the address of
directive handler relative to the beginning of preprocessor module. If symbol
is found in the table, the "get_symbol" clears the carry flag and returns the
found identifier in AX. Also it leaves the ESI pointing to the first byte after
the symbol data (in this case - to the next element of line). Otherwise it sets
the carry flag and leaves the ESI and ECX unchanged.
  When the symbol is recognized as directive, its first byte is replaced with







|





|

|
|
|
|
|







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
of prioritized constants - to detect such definition preprocessor checks
whether the first two data portions are symbols, and whether the second symbol
is the word "fix". If such situation is detected, preprocessor jumps to the
"define_fix_constant" handler. Otherwise it calls the "process_fix_constants"
routine, which checks the line for occurences of prioritized symbolic constants
and if any are found, it replaces them with their values.
  In case when the line that is preprocessed is not line converted directly
from source, but the line generated by macroinstruction, the prioritized
constants and their definitions are not detected and processed in such line
(since they were already processed in the original source line that generated
this new one). Instead, it calls the "process_macro_operators" routine, which
does some processing specific to lines generated by macroinstruction - it will
be explained in details later.
  After this initial processing is finished, the main check for directives and
macroinstructions comes. If the first element of line is the symbol, preprocessor
checks whether is it a directive with the "get_symbol" routine. This procedure
needs ESI to point to the data of symbol, ECX to contain the length of symbol
and EDI to point to the table of symbols that have to be recognized. Each entry
in that table begins with one byte containing the length of symbol, then this
amount of bytes containing the symbol itself and then one 16-bit word containing
identifier of the symbol. In case of directives the identifier is the address of
directive handler relative to the beginning of preprocessor module. If symbol
is found in the table, the "get_symbol" clears the carry flag and returns the
found identifier in AX. Also it leaves the ESI pointing to the first byte after
the symbol data (in this case - to the next element of line). Otherwise it sets
the carry flag and leaves the ESI and ECX unchanged.
  When the symbol is recognized as directive, its first byte is replaced with