home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
program
/
zsm.arc
/
OFMT.DOC
< prev
next >
Wrap
Text File
|
1991-08-11
|
8KB
|
268 lines
Format of .O and .L files.
The whole mechanism of processing .O files revolves around 0x82 bytes
in the data stream: these are used as an escape value. Normal data that is to
be linked in appears in the output file byte for byte, and is copied straight
over by ZLINK. When ZLINK encounters a 0x82 byte, then it does not pass it
over, instead it takes special action depending on the value of the next byte,
known as the flag byte. In the explanations below, the term "current segment"
is used to refer to whichever segment code is being generated for, and the
base of the current segment is the point at which code generation for the
appropriate segment started in the .O file being processed.
0x82: escaped 0x82 byte in data stream - in order that these bytes can
appear, they must be escaped with themselves, so the line:
db 1,0x82,2
in the source would give:
0x01 (first byte straight over)
0x82 (escape)
0x82 (the 0x82 byte from the db)
0x02 (and the last byte)
in the .O file.
0x27: internal cseg reference:
0x22: internal dseg reference:
0x5e: internal useg reference: These three are grouped together as their
behavior is similar: following the flag byte are two more
bytes that give the word offset from the base of the segment
being referred to: as an example, if the label foo: appeared
0x20 bytes into the cseg section of the current .O file, then
the source line:
call foo
would generate the following:
0xcd (call)
0x82 (escape)
0x27 (flag)
0x20 (low byte of offset)
0x00 (high byte of offset)
It should be noted that if either byte of the offset is 0x82
then it is NOT escaped in any way, when reading word offsets
ZLINK simply picks up the next two bytes regardless.
0x24: external reference: when ZSM cannot resolve a reference to one of the
above three, it generates one of these instead: it is similar
to the above, but it also includes the name of the external
label following the offset word, terminated by another 0x82
byte, so:
ld hl, bar - 2
where bar is not defined in this module would give:
0x21 (ld hl,....)
0x82 (escape)
0x24 (flag)
0xfe (low byte of offset (see the -2))
0xff (high byte of offset)
0x62 ('b' of bar)
0x61 ('a' of bar)
0x72 ('r' of bar)
0x82 (terminate the label)
The comment about 0x82 bytes in the offset of internal
references also applies here.
0x3a: define an external label: when a label is extern'ed by use of the
extern directive, this is how it gets transferred to the
.O file: at the appropriate spot an escape, 0x3a flag, and
the name appear again terminated by a 0x82, so:
.extern fox
fox: inc a
would give:
0x82 (escape)
0x3a (flag)
0x66 ('f' of fox)
0x6f ('o' of fox)
0x78 ('x' of fox)
0x82 (terminate)
0x3c (inc a)
0x2d: enter the cseg section:
0x2b: enter the dseg section:
0x2a: enter the useg section:
0x40: terminate the file: In order to keep the three segments apart, these
sequences are used: Note that the 0x82, 0x2d should be the
first thing in the .O file, the action of ZLINK if it comes
across anything else is not defined, and ZLINK stops after
it reaches the 0x82, 0x40 sequence. ZLINK also expects to find
the middle two sequences, even if any of the sections are
empty, the appropriate sequence MUST be there, or to put it
another way, the absolute minimum that can appear in a .O file
is:
0x82 (escape)
0x2d (enter cseg)
0x82 (escape)
0x2b (enter dseg)
0x82 (escape)
0x2a (enter useg)
0x82 (escape)
0x40 (termiate the .O file)
Note also that ZLINK expects to get the sections in the order
shown above, and each section can only appear once in the
file. In general usage, a .O file would be:
0x82 (escape)
0x2d (enter cseg)
0x21 (first byte of data ...)
CSEG SECTION
0x82 (escape)
0x2b (enter dseg)
DSEG SECTION
0x82 (escape)
0x2a (enter useg)
USEG SECTION
0x82 (escape)
0x40 (termiate the .O file)
The reason for showing one byte of code in the cseg section
is that while code is being generated for that section and
only while code is being generated, the base of the current
segment is the address at whice the 0x21 byte appears in the
output file. There is a special limitation that applies to the
useg section in that it can only contain external label
definitions (flag byte 0x3a), and ds / org sequences (flag
byte 0x3e).
0x3e: process a ds opcode or an org directive: these two are handled in a
similar fashion: following the flag byte is the address at
which this sequence should end, considered as an offset from
the base of the current segment being processed, so:
.org 0x0200
in the source would give:
0x82 (escape)
0x3e (flag)
0x00 (low byte)
0x02 (high byte)
as org's always refer to the base of the current segment; and
if the following ds appeared at address 0x0110 in some
segment:
ds 0x64
the resulting code woude be:
0x82 (escape)
0x3e (flag)
0x74 (low byte)
0x01 (high byte)
Note how the termination address is 0x174: the sum of the
start address (0x110) and the size (0x64).
As is mentioned in LIB.DOC, .L files are similar to .O files, with the
exception that some additional information appears to keep the modules apart,
and to provide naming and linking information. The following flag bytes will
appear in library files:
0x3b: start a new .O module in the current library: following this is
the name of the module, always in upper case, terminated by
another 0x82 byte.
0x26: flag an external label that this module can resolve: in order that
ZLINK can know which undefined labels a module can resolve,
a list is provided at the start, each entry in the list has
the following form: (example given for label bar)
0x82 (escape)
0x26 (flag)
0x62 ('b' of bar)
0x61 ('a' of bar)
0x72 ('r' of bar)
0x82 (terminate this sequence)
0x2e: terminate list of labels that can be resolved by this module: after
all the external labels have been provided, include this
sequence to tell ZLINK to stop scanning for externals.
so taking the example from ZSM.DOC:
.lib "strcpy" ; generating STRCPY.O
.extern _strcpy ; _strcpy is the only external label
_strcpy: ; here it is
call #arg2 ; and the code ....
the entire sequence generated would be:
0x82 (escape)
0x3b (flag a new .O module)
0x53 ('S' of STRCPY)
0x54 ('T' of STRCPY)
0x52 ('R' of STRCPY)
0x43 ('C' of STRCPY)
0x50 ('P' of STRCPY)
0x59 ('Y' of STRCPY)
0x82 (terminate .O module name definition)
; the above sequence gives the name of the module, note that
; the .O is not included, and that the bytes in the .L file
; have been converted to upper case.
0x82 (escape)
0x26 (flag a label resolved in this module)
0x5f ('_' of _strcpy)
0x73 ('s' of _strcpy)
0x54 ('t' of _strcpy)
0x52 ('r' of _strcpy)
0x43 ('c' of _strcpy)
0x50 ('p' of _strcpy)
0x59 ('y' of _strcpy)
0x82 (terminate label)
; this section tells ZLINK the name of the one label that this
; module can resolve, if more than one label can be resolved
; then multiple 0x26 sequences can be included.
0x82 (escape)
0x2e (flag end of list)
; terminate the list of labels we can resolve
0x82 (escape)
0x2d (flag entry to cseg section)
0xcd (call .....)
At this point the code continues exactly as per a normal .O
file, until the terminating 0x82, 0x40 has been seen.
at this point either a new .O file will be defined with a
0x3b sequence, or ....
0x3d: terminate the library: following the terminating 0x82, 0x40 of the
last .O module in the library, comes the sequence:
0x82 (escape)
0x3d (flag)
which marks the end of the library.