4 * (C) Copyright 1989-1995
21 * The module asout.c contains all the functions used to
22 * generate the .REL assembler output file.
25 * The assemblers' output object file is an ascii file containing
26 * the information needed by the linker to bind multiple object
27 * modules into a complete loadable memory image.
29 * The object module contains the following designators:
36 * H Most significant byte first
37 * L Least significant byte first
44 * R Relocation information
45 * P Paging information
50 * The first line of an object module contains the [XDQ][HL]
51 * format specifier (i.e. XH indicates a hexidecimal file with
52 * most significant byte first) for the following designators.
57 * H aa areas gg global symbols
59 * The header line specifies the number of areas(aa) and the
60 * number of global symbols(gg) defined or referenced in this ob-
61 * ject module segment.
68 * The module line specifies the module name from which this
69 * header segment was assembled. The module line will not appear
70 * if the .module directive was not used in the source program.
81 * The symbol line defines (Def) or references (Ref) the symbol
82 * 'string' with the value nnnn. The defined value is relative to
83 * the current area base address. References to constants and ex-
84 * ternal global symbols will always appear before the first area
85 * definition. References to external symbols will have a value of
91 * A label size ss flags ff
93 * The area line defines the area label, the size (ss) of the
94 * area in bytes, and the area flags (ff). The area flags specify
95 * the ABS, REL, CON, OVR, and PAG parameters:
97 * OVR/CON (0x04/0x00 i.e. bit position 2)
99 * ABS/REL (0x08/0x00 i.e. bit position 3)
101 * PAG (0x10 i.e. bit position 4)
106 * T xx xx nn nn nn nn nn ...
108 * The T line contains the assembled code output by the assem-
109 * bler with xx xx being the offset address from the current area
110 * base address and nn being the assembled instructions and data in
116 * R 0 0 nn nn n1 n2 xx xx ...
118 * The R line provides the relocation information to the linker.
119 * The nn nn value is the current area index, i.e. which area the
120 * current values were assembled. Relocation information is en-
121 * coded in groups of 4 bytes:
123 * 1. n1 is the relocation mode and object format
124 * 1. bit 0 word(0x00)/byte(0x01)
125 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
126 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
127 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
129 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
130 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
131 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
132 * 8. bit 7 normal(0x00)/MSB of value
134 * 2. n2 is a byte index into the corresponding (i.e. pre-
135 * ceeding) T line data (i.e. a pointer to the data to be
136 * updated by the relocation). The T line data may be
137 * 1-byte or 2-byte byte data format or 2-byte word
140 * 3. xx xx is the area/symbol index for the area/symbol be-
141 * ing referenced. the corresponding area/symbol is found
142 * in the header area/symbol lists.
145 * The groups of 4 bytes are repeated for each item requiring relo-
146 * cation in the preceeding T line.
151 * P 0 0 nn nn n1 n2 xx xx
153 * The P line provides the paging information to the linker as
154 * specified by a .setdp directive. The format of the relocation
155 * information is identical to that of the R line. The correspond-
156 * ing T line has the following information:
157 * T xx xx aa aa bb bb
159 * Where aa aa is the area reference number which specifies the
160 * selected page area and bb bb is the base address of the page.
161 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
162 * specified in the P line. The linker will verify that the base
163 * address is on a 256 byte boundary and that the page length of an
164 * area defined with the PAG type is not larger than 256 bytes.
166 * The linker defaults any direct page references to the first
167 * area defined in the input REL file. All ASxxxx assemblers will
168 * specify the _CODE area first, making this the default page area.
171 * asout.c contains the following functions:
192 * The module asout.c contains the following local variables:
193 * int rel[] relocation data for code/data array
194 * int * relp pointer to rel array
195 * int txt[] assembled code/data array
196 * int * txtp pointer to txt array
205 char *txtp = { &txt[0] };
206 char *relp = { &rel[0] };
208 /*)Function VOID outab(b)
210 * int b assembler data word
212 * The function outab() processes a single word of
213 * assembled data in absolute format.
216 * int * txtp pointer to data word
219 * int oflag -o, generate relocatable output flag
220 * int pass assembler pass number
223 * VOID outchk() asout.c
224 * VOID out_lb() asout.c
227 * The current assembly address is incremented by 1.
243 /*)Function VOID outaw(w)
245 * int w assembler data word
247 * The function outaw() processes a single word of
248 * assembled data in absolute format.
251 * int * txtp pointer to data word
254 * int oflag -o, generate relocatable output flag
255 * int pass assembler pass number
258 * VOID outchk() asout.c
259 * VOID out_lw() asout.c
262 * The current assembly address is incremented by 2.
278 /*)Function VOID outrb(esp, r)
280 * expr * esp pointer to expr structure
281 * int r relocation mode
283 * The function outrb() processes a byte of generated code
284 * in either absolute or relocatable format dependent upon
285 * the data contained in the expr structure esp. If the
286 * .REL output is enabled then the appropriate information
287 * is loaded into the txt and rel buffers.
290 * int n symbol/area reference number
291 * int * relp pointer to rel array
292 * int * txtp pointer to txt array
295 * sym dot defined as sym[0]
296 * int oflag -o, generate relocatable output flag
297 * int pass assembler pass number
300 * VOID aerr() assubr.c
301 * VOID outchk() asout.c
302 * VOID out_lb() asout.c
303 * VOID out_rb() asout.c
304 * VOID out_tb() asout.c
307 * The current assembly address is incremented by 1.
312 register struct expr *esp;
318 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
319 out_lb(lobyte(esp->e_addr),0);
322 *txtp++ = lobyte(esp->e_addr);
325 r |= R_BYTE | R_BYT2 | esp->e_rlcf;
327 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
329 out_lb(lobyte(esp->e_addr),r|R_RELOC);
335 n = esp->e_base.e_sp->s_ref;
338 n = esp->e_base.e_ap->a_ref;
341 *relp++ = txtp - txt - 2;
349 /*)Function VOID outrw(esp, r)
351 * expr * esp pointer to expr structure
352 * int r relocation mode
354 * The function outrw() processes a word of generated code
355 * in either absolute or relocatable format dependent upon
356 * the data contained in the expr structure esp. If the
357 * .REL output is enabled then the appropriate information
358 * is loaded into the txt and rel buffers.
361 * int n symbol/area reference number
362 * int * relp pointer to rel array
363 * int * txtp pointer to txt array
366 * sym dot defined as sym[0]
367 * int oflag -o, generate relocatable output flag
368 * int pass assembler pass number
371 * VOID aerr() assubr.c
372 * VOID outchk() asout.c
373 * VOID out_lw() asout.c
374 * VOID out_rw() asout.c
375 * VOID out_tw() asout.c
378 * The current assembly address is incremented by 2.
383 register struct expr *esp;
389 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
390 out_lw(esp->e_addr,0);
396 r |= R_WORD | esp->e_rlcf;
400 out_lw(hibyte(esp->e_addr),r|R_RELOC);
402 out_lw(lobyte(esp->e_addr),r|R_RELOC);
405 out_lw(esp->e_addr,r|R_RELOC);
411 n = esp->e_base.e_sp->s_ref;
414 n = esp->e_base.e_ap->a_ref;
417 *relp++ = txtp - txt - 2;
425 /*)Function VOID outdp(carea, esp)
427 * area * carea pointer to current area strcuture
428 * expr * esp pointer to expr structure
430 * The function outdp() flushes the output buffer and
431 * outputs paging information to the .REL file.
434 * int n symbol/area reference number
435 * int r relocation mode
436 * int * relp pointer to rel array
437 * int * txtp pointer to txt array
440 * int oflag -o, generate relocatable output flag
441 * int pass assembler pass number
444 * VOID outbuf() asout.c
445 * VOID outchk() asout.c
446 * VOID out_rw() asout.c
447 * VOID out_tw() asout.c
450 * Output buffer flushed to .REL fiel.
451 * Paging information dumped to .REL file.
456 register struct area *carea;
457 register struct expr *esp;
461 if (oflag && pass==2) {
463 out_tw(carea->a_ref);
465 if (esp->e_flag || esp->e_base.e_ap!=NULL) {
468 n = esp->e_base.e_sp->s_ref;
471 n = esp->e_base.e_ap->a_ref;
474 *relp++ = txtp - txt - 2;
481 /*)Function VOID outall()
483 * The function outall() will output any bufferred assembled
484 * data and relocation information (during pass 2 if the .REL
485 * output has been enabled).
491 * int oflag -o, generate relocatable output flag
492 * int pass assembler pass number
495 * VOID outbuf() asout.c
498 * assembled data and relocation buffers will be cleared.
504 if (oflag && pass==2)
508 /*)Function VOID outdot()
510 * The function outdot() outputs information about the
511 * current program counter value (during pass 2 if the .REL
512 * output has been enabled).
518 * int oflag -o, generate relocatable output flag
519 * int pass assembler pass number
522 * int fprintf() c_library
526 * assembled data and relocation buffers will be cleared.
532 if (oflag && pass==2) {
534 out(txt,(int) (txtp-txt));
537 out(rel,(int) (relp-rel));
544 /*)Function outchk(nt, nr)
546 * int nr number of additional relocation words
547 * int nt number of additional data words
549 * The function outchk() checks the data and relocation buffers
550 * for space to insert the nt data words and nr relocation words.
551 * If space is not available then output the current data and
552 * initialize the data buffers to receive the new data.
555 * area * ap pointer to an area structure
556 * int * relp pointer to rel array
557 * int * txtp pointer to txt array
560 * sym dot defined as sym[0]
563 * VOID outbuf() asout.c
566 * Data and relocation buffers may be emptied and initialized.
572 register struct area *ap;
574 if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
579 if ((ap = dot.s_area) != NULL) {
580 *relp++ = R_WORD|R_AREA;
587 /*)Function VOID outbuf()
589 * The function outbuf() will output any bufferred data
590 * and relocation information to the .REL file. The output
591 * buffer pointers and counters are initialized.
594 * int rel[] relocation data for code/data array
595 * int * relp pointer to rel array
596 * int txt[] assembled code/data array
597 * int * txtp pointer to txt array
600 * FILE * ofp relocation output file handle
606 * All bufferred data written to .REL file and
607 * buffer pointers and counters initialized.
614 if (txtp > &txt[2]) {
616 out(txt,(int) (txtp-txt));
619 out(rel,(int) (relp-rel));
626 /*)Function VOID outgsd()
628 * The function outgsd() performs the following:
629 * (1) outputs the .REL file radix
630 * (2) outputs the header specifying the number
631 * of areas and global symbols
632 * (3) outputs the module name
633 * (4) set the reference number and output a symbol line
634 * for all external global variables and absolutes
635 * (5) output an area name, set reference number and output
636 * a symbol line for all global relocatables in the area.
637 * Repeat this proceedure for all areas.
640 * area * ap pointer to an area structure
641 * sym * sp pointer to a sym structure
644 * int c string character value
645 * int narea number of code areas
646 * char * ptr string pointer
647 * int nglob number of global symbols
648 * int rn symbol reference number
651 * area * areap pointer to an area structure
652 * char module[] module name string
653 * sym * symhash[] array of pointers to NHASH
654 * linked symbol lists
655 * int xflag -x, listing radix flag
658 * int fprintf() c_library
659 * VOID outarea() asout.c
660 * VOID outsym() asout.c
661 * int putc() c_library
664 * All symbols are given reference numbers, all symbol
665 * and area information is output to the .REL file.
671 register struct area *ap;
672 register struct sym *sp;
675 int c, narea, nglob, rn;
680 narea = areap->a_ref + 1;
683 * Number of global references/absolutes
686 for (i = 0; i < NHASH; ++i) {
689 if (sp->s_flag&S_GBL)
696 * Output Radix and number of areas and symbols
699 fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
700 fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
703 fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
704 fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
707 fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
708 fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
717 while (ptr < &module[NCPS]) {
718 if ((c = *ptr++) != 0)
725 * Global references and absolutes.
728 for (i=0; i<NHASH; ++i) {
731 if (sp->s_area==NULL && sp->s_flag&S_GBL) {
740 * Global relocatables.
742 for (i=0; i<narea; ++i) {
744 while (ap->a_ref != i)
747 for (j=0; j<NHASH; ++j) {
750 if (sp->s_area==ap && sp->s_flag&S_GBL) {
760 /*)Function VOID outarea(ap)
762 * area * ap pointer to an area structure
764 * The function outarea() outputs the A line to the .REL
765 * file. The A line contains the area's name, size, and
769 * char * ptr pointer to area id string
770 * int c character value
773 * FILE * ofp relocation output file handle
774 * int xflag -x, listing radix flag
777 * int fprintf() c_library
778 * int putc() c_library
781 * The A line is sent to the .REL file.
786 register struct area *ap;
793 while (ptr < &ap->a_id[NCPS]) {
794 if ((c = *ptr++) != 0)
798 fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
801 fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
804 fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
808 /*)Function VOID outsym(sp)
810 * sym * sp pointer to a sym structure
812 * The function outsym() outputs the S line to the .REL
813 * file. The S line contains the symbols name and whether the
814 * the symbol is defined or referenced.
817 * char * ptr pointer to symbol id string
818 * int c character value
821 * FILE * ofp relocation output file handle
822 * int xflag -x, listing radix flag
825 * int fprintf() c_library
826 * int putc() c_library
829 * The S line is sent to the .REL file.
834 register struct sym *sp;
841 while (ptr < &sp->s_id[NCPS]) {
842 if ((c = *ptr++) != 0)
845 fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
847 fprintf(ofp, "%04X\n", sp->s_addr);
850 fprintf(ofp, "%06o\n", sp->s_addr);
853 fprintf(ofp, "%05u\n", sp->s_addr);
857 /*)Function VOID out(p, n)
859 * int n number of words to output
860 * int * p pointer to data words
862 * The function out() outputs the data words to the .REL file
863 * int the specified radix.
869 * FILE * ofp relocation output file handle
870 * int xflag -x, listing radix flag
873 * int fprintf() c_library
876 * Data is sent to the .REL file.
886 fprintf(ofp, " %02X", (*p++)&0377);
889 fprintf(ofp, " %03o", (*p++)&0377);
892 fprintf(ofp, " %03u", (*p++)&0377);
897 /*)Function VOID out_lb(b, t)
899 * int b assembled data
900 * int t relocation type
902 * The function out_lb() copies the assembled data and
903 * its relocation type to the list data buffers.
909 * int * cp pointer to assembler output array cb[]
910 * int * cpt pointer to assembler relocation type
917 * Pointers to data and relocation buffers incremented by 1.
924 if (cp < &cb[NCODE]) {
930 /*)Function VOID out_lw(n, t)
932 * int n assembled data
933 * int t relocation type
935 * The function out_lw() copies the assembled data and
936 * its relocation type to the list data buffers.
942 * int * cp pointer to assembler output array cb[]
943 * int * cpt pointer to assembler relocation type
950 * Pointers to data and relocation buffers incremented by 2.
958 out_lb(hibyte(n),t ? t|R_HIGH : 0);
962 out_lb(hibyte(n),t ? t|R_HIGH : 0);
966 /*)Function VOID out_rw(n)
970 * The function out_rw() outputs the relocation (R)
971 * data word as two bytes ordered according to hilo.
974 * int * relp pointer to rel array
980 * int lobyte() asout.c
981 * int hibyte() asout.c
984 * Pointer to relocation buffer incremented by 2.
1000 /*)Function VOID out_tw(n)
1004 * The function out_tw() outputs the text (T)
1005 * data word as two bytes ordered according to hilo.
1008 * int * txtp pointer to txt array
1014 * int lobyte() asout.c
1015 * int hibyte() asout.c
1018 * Pointer to relocation buffer incremented by 2.
1026 *txtp++ = hibyte(n);
1027 *txtp++ = lobyte(n);
1029 *txtp++ = lobyte(n);
1030 *txtp++ = hibyte(n);
1034 /*)Function int lobyte(n)
1038 * The function lobyte() returns the lower byte of
1060 /*)Function int hibyte(n)
1064 * The function hibyte() returns the higher byte of
1083 return ((n>>8)&0377);