Dec 072017
 
C users' group disk # 242, cross assemblers for 8051, 6811, 63701 micro controllers written in portable c language.
File XASM.ZIP from The Programmer’s Corner in
Category Assembly Language
C users’ group disk # 242, cross assemblers for 8051, 6811, 63701 micro controllers written in portable c language.
File Name File Size Zip Size Zip Type
8052BITS.LIB 512 302 deflated
A51.C 17152 4250 deflated
A51.DOC 46336 11665 deflated
A51.H 12160 4106 deflated
A51EVAL.C 10752 3414 deflated
A51UTIL.C 14080 4201 deflated
A611.C 11904 3310 deflated
A611.DOC 44544 11286 deflated
A611.H 10880 3738 deflated
A611EVAL.C 9856 3090 deflated
A611UTIL.C 15360 4101 deflated
A63.C 12288 3491 deflated
A63.DOC 45952 11533 deflated
A63.H 11008 3781 deflated
A63EVAL.C 9984 3167 deflated
A63UTIL.C 15488 4187 deflated
CG242-0I.003 128 5 deflated
READ.ME3 3968 1509 deflated
SUBMIT.DSK 2944 1426 deflated
TEST51.ASM 4352 1121 deflated
TEST611.ASM 4736 1276 deflated
TEST63.ASM 4864 1275 deflated
TPCREAD.ME 199 165 deflated

Download File XASM.ZIP Here

Contents of the A51.DOC file


/*
HEADER:CUG242;
TITLE:8051 Cross-Assembler (Portable);
FILENAME:A51.DOC;
VERSION:0.1;
DATE:10/13/1987;
SEE-ALSO:A51.H;
AUTHORS:William C. Colley III;
*/














8051 Cross-Assembler (Portable)


Version 0.1


Copyright (c) 1985,1987 William C. Colley, III






The manual such as it is.











Legal Note: This package may be used for any commercial or
non-commercial purpose. It may be copied and
distributed freely provided that any fee charged
by the distributor of the copy does not exceed the
sum of: 1) the cost of the media the copy is
written on, 2) any required costs of shipping the
copy, and 3) a nominal handling fee. Any other
distribution requires the written permission of
the author. Also, the author's copyright notices
shall not be removed from the program source, the
program object, or the program documentation.














Table of Contents

1.0 How to Use the Cross-Assembler Package .................. 3
2.0 Format of Cross-Assembler Source Lines .................. 4
2.1 Labels ............................................. 5
2.2 Numeric Constants .................................. 6
2.3 String Constants ................................... 6
2.4 Expressions ........................................ 6
2.5 Bit Expressions .................................... 7
3.0 Machine Opcodes ......................................... 8
3.1 Opcodes -- No Arguments ............................ 8
3.2 Opcodes -- One Argument ............................ 8
3.3 Opcodes -- Two Arguments in Order .................. 9
3.4 Opcodes -- Two Arguments in Either Order ........... 9
3.5 Opcodes -- Three Arguments in Order ................ 9
3.6 Opcodes -- Relative Branches ....................... 9
3.7 Opcodes -- Absolute Branches ....................... 9
3.8 Opcodes -- Long Branches ........................... 10
3.9 Opcodes -- MOV ..................................... 10
4.0 Pseudo Opcodes .......................................... 10
4.1 Pseudo-ops -- BIT .................................. 10
4.2 Pseudo-ops -- DB ................................... 10
4.3 Pseudo-ops -- DS ................................... 11
4.4 Pseudo-ops -- DW ................................... 11
4.5 Pseudo-ops -- END .................................. 11
4.6 Pseudo-ops -- EQU .................................. 12
4.7 Pseudo-ops -- IF, ELSE, ENDIF ...................... 12
4.8 Pseudo-ops -- INCL ................................. 13
4.9 Pseudo-ops -- ORG .................................. 13
4.10 Pseudo-ops -- PAGE ................................. 13
4.11 Pseudo-ops -- REG .................................. 14
4.12 Pseudo-ops -- SET .................................. 14
4.13 Pseudo-ops -- TITL ................................. 14
5.0 Assembly Errors ......................................... 14
5.1 Error * -- Missing Statement ....................... 15
5.2 Error ( -- Parenthesis Imbalance ................... 15
5.3 Error " -- Missing Quotation Mark .................. 15
5.4 Error B -- Branch Target Out of Bounds ............. 15
5.5 Error D -- Illegal Digit ........................... 15
5.6 Error E -- Illegal Expression ...................... 16
5.7 Error I -- IF-ENDIF Imbalance ...................... 16
5.8 Error L -- Illegal Label ........................... 16
5.9 Error M -- Multiply Defined Label .................. 16
5.10 Error O -- Illegal Opcode .......................... 16
5.11 Error P -- Phasing Error ........................... 17
5.12 Error S -- Illegal Syntax .......................... 17
5.13 Error T -- Too Many Arguments ...................... 17
5.14 Error U -- Undefined Label ......................... 17
5.15 Error V -- Illegal Value ........................... 17
6.0 Warning Messages ........................................ 17
6.1 Warning -- Illegal Option Ignored .................. 18
6.2 Warning -- -l Option Ignored -- No File Name ....... 18
6.3 Warning -- -o Option Ignored -- No File Name ....... 18
6.4 Warning -- Extra Source File Ignored ............... 18
6.5 Warning -- Extra Listing File Ignored .............. 18


1



6.6 Warning -- Extra Object File Ignored ............... 18

7.0 Fatal Error Messages .................................... 18
7.1 Fatal Error -- No Source File Specified ............ 18
7.2 Fatal Error -- Source File Did Not Open ............ 18
7.3 Fatal Error -- Listing File Did Not Open ........... 19
7.4 Fatal Error -- Object File Did Not Open ............ 19
7.5 Fatal Error -- Error Reading Source File ........... 19
7.6 Fatal Error -- Disk or Directory Full .............. 19
7.7 Fatal Error -- File Stack Overflow ................. 19
7.8 Fatal Error -- If Stack Overflow ................... 19
7.9 Fatal Error -- Too Many Symbols .................... 19














































2



1.0 How to Use the Cross-Assembler Package

First, the question, "What does a cross-assembler do?" needs
to be addressed as there is considerable confusion on this point.
A cross-assembler is just like any other assembler except that it
runs on some CPU other than the one for which it assembles code.
For example, this package assembles 8051 source code into 8051
object code, but it runs on an 8080, a Z-80, an 8088, or whatever
other CPU you happen to have a C compiler for. The reason that
cross-assemblers are useful is that you probably already have a
CPU with memory, disk drives, a text editor, an operating system,
and all sorts of hard-to-build or expensive facilities on hand.
A cross-assembler allows you to use these facilites to develop
code for an 8051.

This program requires one input file (your 8051 source code) and
zero to two output files (the listing and the object). The input
file MUST be specified, or the assembler will bomb on a fatal
error. The listing and object files are optional. If no listing
file is specified, no listing is generated, and if no object file
is specified, no object is generated. If the object file is
specified, the object is written to this file in "Intel
hexadecimal" format.

The command line for the cross-assembler looks like this:

A51 source_file { >list_file } { -o object_file }

where the { } indicates that the specified item is optional.

Some examples are in order:

a51 test51.asm source: test51.asm
listing: none
object: none

a51 test51.asm -l test51.prn source: test51.asm
listing: test51.prn
object: none

a51 test51.asm -o test51.hex source: test51.asm
listing: none
object: test51.hex

a51 test51.asm -l test51.prn -o test51.hex
source: test51.asm
listing: test51.prn
object: test51.hex

The order in which the source, listing, and object files are
specified does not matter. Note that no default file name exten-
sions are supplied by the assembler as this gives rise to porta-
bility problems.




3



2.0 Format of Cross-Assembler Source Lines

The source file that the cross-assembler processes into a
listing and an object is an ASCII text file that you can prepare
with whatever editor you have at hand. The most-significant
(parity) bit of each character is cleared as the character is
read from disk by the cross-assembler, so editors that set this
bit (such as WordStar's document mode) should not bother this
program. All printing characters, the ASCII TAB character (09H),
and newline character(s) are processed by the assembler. All
other characters are passed through to the listing file, but are
otherwise ignored.

The source file is divided into lines by newline char-
acter(s). The internal buffers of the cross-assembler will
accommodate lines of up to 255 characters which should be more
than ample for almost any job. If you must use longer lines,
change the constant MAXLINE in file A51.H and recompile the
cross-assembler. Otherwise, you will overflow the buffers, and
the program will mysteriously crash.

Each source line is made up of three fields: the label
field, the opcode field, and the argument field. The label field
is optional, but if it is present, it must begin in column 1.
The opcode field is optional, but if it is present, it must not
begin in column 1. If both a label and an opcode are present,
one or more spaces and/or TAB characters must separate the two.
If the opcode requires arguments, they are placed in the argument
field which is separated from the opcode field by one or more
spaces and/or TAB characters. Finally, an optional comment can
be added to the end of the line. This comment must begin with a
semicolon which signals the assembler to pass the rest of the
line to the listing and otherwise ignore it. Thus, the source
line looks like this:

{label}{ opcode{ arguments}}{;commentary}

where the { } indicates that the specified item is optional.

Some examples are in order:

column 1
|
v
GRONK DJNZ R1, LOOP ; This line has everything.
INC R1 ; This line has no label.
BEEP ; This line has no opcode.
; This line has no label and no opcode.

; The previous line has nothing at all.
END ; This line has no argument.






4



2.1 Labels

A label is any sequence of alphabetic or numeric characters
starting with an alphabetic. The legal alphabetics are:

! $ % & : ? [ \ ] ^ _ ` { | } ~ A-Z a-z

The numeric characters are the digits 0-9. Note that "A" is not
the same as "a" in a label. This can explain mysterious U
(undefined label) errors occurring when a label appears to be
defined.

A label is permitted on any line except a line where the
opcode is IF, ELSE, or ENDIF. The label is assigned the value of
the assembly program counter before any of the rest of the line
is processed except when the opcode is BIT, EQU, ORG, REG, or
SET.

Labels can have the same name as opcodes, but they cannot
have the same name as pre-defined bit variables, operators,
registers, or pre-defined byte addresses. The reserved names
are:

Pre-defined bit variables:

AC CY EA ES ET0 ET1
EX0 EX1 F0 IE0 IE1 IT0
IT1 OV P PS PT0 PT1
PX0 PX1 RS0 RS1 RB8 REN
RI SM0 SM1 SM2 TB8 TF0
TF1 TI TR0 TR1

Operators:

AND EQ GE GT HIGH LE
LOW LT MOD NE NOT OR
SHL SHR XOR

Registers:

A AB C DPTR PC R0
R1 R2 R3 R4 R5 R6
R7

Pre-defined byte addresses:

$ ACC B DPH DPL IE
IP P0 P1 P2 P3 PCON
PSW SBUF SCON SP TCON TH0
TH1 TL0 TL1 TMOD

If a label is used in an expression before it is assigned a
value, the label is said to be "forward-referenced." For
example:



5



L1 EQU L2 + 1 ; L2 is forward-referenced here.

L2
L3 EQU L2 + 1 ; L2 is not forward-referenced here.


2.2 Numeric Constants

Numeric constants are formed according to the Intel
convention. A numeric constant starts with a numeric character
(0-9), continues with zero or more digits (0-9, A-F), and ends
with an optional base designator. The base designators are H for
hexadecimal, none or D for decimal, O or Q for octal, and B for
binary. The hex digits a-f are converted to upper case by the
assembler. Note that a numeric constant cannot begin with A-F as
it would be indistinguishable from a label. Thus, all of the
following evaluate to 255 (decimal):

0ffH 255 255D 377O 377Q 11111111B


2.3 String Constants

A string constant is zero or more characters enclosed in
either single quotes (' ') or double quotes (" "). Single quotes
only match single quotes, and double quotes only match double
quotes, so if you want to put a single quote in a string, you can
do it like this: "'". In all contexts except the DB statement,
the first character or two of the string constant are all that
are used. The rest is ignored. Noting that the ASCII codes for
"A" and "B" are $41 and $42, respectively, will explain the
following examples:

"" and '' evaluate to $0000
"A" and 'A' evaluate to $0041
"AB" evaluates to $4142

Note that the null string "" is legal and evaluates to $0000.


2.4 Expressions

An expression is made up of labels, numeric constants, and

string constants glued together with arithmetic operators,
logical operators, and parentheses in the usual way that
algebraic expressions are made. Operators have the following
fairly natural order of precedence:

Highest anything in parentheses
unary +, unary -
*, /, MOD, SHL, SHR
binary +, binary -
LT, LE, EQ, GE, GT, NE
NOT
AND
OR, XOR


6



Lowest HIGH, LOW


A few notes about the various operators are in order:

1) The remainder operator MOD yields the remainder from
dividing its left operand by its right operand.

2) The shifting operators SHL and SHR shift their left
operand to the left or right the number of bits
specified by their right operand.

3) The relational operators LT, LE, EQ, GE, GT, and NE can
also be written as <, <= or =<, =, >= or =>, and <> or
><, respectively. They evaluate to 0FFFFH if the
statement is true, 0 otherwise.

4) The logical opeators NOT, AND, OR, and XOR do bitwise
operations on their operand(s).

5) HIGH and LOW extract the high or low byte, of an
expression.

6) The special symbol $ can be used in place of a label or
constant to represent the value of the program counter
before any of the current line has been processed.

Some examples are in order at this point:

2 + 3 * 4 evaluates to 14
(2 + 3) * 4 evaluates to 20
NOT %11110000 XOR %00001010 evaluates to %00000101
HIGH 1234H SHL 1 evaluates to $0024
001Q EQ 0 evaluates to 0
001Q = 2 SHR 1 evaluates to $FFFF

All arithmetic is unsigned with overflow from the 16-bit
word ignored. Thus:

32768 * 2 evaluates to 0


2.5 Bit Expressions

Byte addresses are specified by expressions as described
above. Bit addresses are specified by a special type of
expression which can take the following three forms:

1) bit_variable

Bit variables are declared with the BIT pseudo-op.
A number of bit variables are pre-defined by the
assembler such as OV for the overflow flag (bit 2 of
location 0E0H).

2) expression_1 . expression_2


7




This yields the bit address of bit expression_2 of
location expression_1. expression_1 must in the range

20H - 2FH or an even multiple of 8 in the range 80H -
0FFH. expression_2 must be in the range 0 - 7. An
illegal value in either expression will cause a V
(value) error.

3) expression

An expression can also specify a bit address by
itself.


3.0 Machine Opcodes

The opcodes of the 8051 processor are divided into groups
below by the type of arguments required in the argument field of
the source line. If an opcode requires multiple arguments, these
must be placed in the argument field in order (unless otherwise
specified) and separated by commas. Some shorthand notations
will be used. They are:

#imm means immediate value (e.g. #012H) in the range
-128 to +255
bit means bit expression as described in section 2.5
dir means byte address in the range 0 - 0FFH
rel means byte address as described in section 3.6
Rn means R0, R1, R2, R3, R4, R5, R6, or R7


3.1 Opcodes -- No Arguments

The following opcodes allow no arguments at all in their
argument fields:

NOP RET RETI


3.2 Opcodes -- One Argument

The following opcodes require one argument. The allowable
argument values for each opcode are listed below:

Argument Value(s) Opcode(s)

A DA, RL, RLC, RR, RRC, SWAP
AB DIV, MUL
dir POP, PUSH
A, Rn, @R0, @R1, or dir DEC
A, DPTR, Rn, @R0, @R1, or dir INC
C, or bit SETB
A, C, or bit CLR, CPL
@A + DPTR JMP



8




3.3 Opcodes -- Two Arguments in Order

The following opcodes require two arguments in the specified
order:

Argument 1 Argument 2 Opcode(s)

A @A + DPTR or @A + PC MOVC
A @R0 or @R1 XCHD
A dir, Rn, @R0, or @R1 XCH
A dir, #imm, Rn, @R0, ADD, ADDC, ANL,
or @R1 ORL, SUBB, XRL
dir A, or #imm ANL, ORL, XRL
C bit, or /bit ANL, ORL
bit rel JB, JBC, JNB
Rn, or @Rn rel DJNZ


3.4 Opcodes -- Two Arguments in Either Order

The following opcodes require two arguments in either order:

Argument 1 Argument 2 Opcode

A @DPTR, @R0, or @R1 MOVX


3.5 Opcodes -- Three Arguments in Order

The CJNE opcode requires three arguments in order. Two sets
of arguments are allowed as follows:

Argument 1 Argument 2 Argument 3

A dir or #imm rel
Rn, @R0, or @R1 #imm rel


3.6 Opcodes -- Relative Branches

The opcodes in this group require one argument. It is an
arithmetic expression that evaluates to an address in the range
-128 to +127 bytes from the address of the first byte of the NEXT
instruction. The opcodes are:

JC JNC JNZ JZ SJMP


3.7 Opcodes -- Absolute Branches

These opcodes require one argument. It is an arithmetic
expression that evaluates to an address on the same 2K page as
the NEXT instruction. The opcodes are:



9



ACALL AJMP



3.8 Opcodes -- Long Branches

The following opcodes require one argument that is an
arithmetic expression with any value.

LCALL LJMP


3.9 Opcodes -- MOV

The MOV opcode requires two arguments. The following table
has the allowable combinations marked with an X:

First Second Argument
Argument A #imm dir Rn @R0 @R1 bit C
A X X X X X
dir X X X X X X
Rn X X X
@R0 X X X
@R1 X X X
bit X
C X
DPTR *

* = The immediate value in this case (only) is not
restricted to the range -128 to +255.


4.0 Pseudo Opcodes

Unlike 8051 opcodes, pseudo opcodes (pseudo-ops) do not
represent machine instructions. They are, rather, directives to
the assembler. These directives require various numbers and
types of arguments. They will be listed individually below.


4.1 Pseudo-ops -- BIT

The BIT pseudo-op allows the user to create bit variables.
It takes the following form:

label BIT bit_expression

The label is mandatory. If it is missing, the assembler will
generate an L (label) error.


4.2 Pseudo-ops -- DB

The DB pseudo-op allows arbitrary bytes to be spliced into
the object code. Its argument is a chain of zero or more
expressions that evaluate to -128 through 255 separated by


10



commas. If a comma occurs with no preceding expression, a 00H
byte is spliced into the object code. The sequence of bytes
0FEH, 0FFH, 00H, 01H, 02H could be spliced into the code with the

following statement:

DB -2, -1, , 1, 2

A special case exists here. If a string constant is entered with
no arithmetic done on it, then the entire string is spliced into
the code stream. Thus, the sequence of bytes 002H, 043H, 041H,
054H, 044H could be spliced into the code with the following
statement:

DB 1 + 1, "CAT", "C" + 1


4.3 Pseudo-ops -- DS

The DS pseudo-op is used to reserve a block of storage for
program variables, or whatever. This storage is not initialized
in any way, so its value at run time will usually be random. The
argument expression (which may contain no forward references) is
added to the assembly program counter. The following statement
would reserve 10 bytes of storage called "STORAGE":

STORAGE DS 10


4.4 Pseudo-ops -- DW

The DW pseudo-op allows 16-bit words to be spliced into the
object code. Its argument is a chain of zero or more expressions
separated by commas. If a comma occurs with no preceding
expression, a word of 0000H is spliced into the code. The word
is placed into memory high byte in low address, low byte in high
address -- the opposite of standard Intel order. The sequence of
bytes 0FFH, 0FEH, 00H, 00H, 01H, 02H could be spliced into the
code with the following statement:

DW 0FFFEH, , 0102H


4.5 Pseudo-ops -- END

The END pseudo-op tells the assembler that the source
program is over. Any further lines of the source file are
ignored and not passed on to the listing. If an argument is
added to the END statement, the value of the argument will be
placed in the execution address slot in the Intel hex object
file. The execution address defaults to the program counter
value at the point where the END was encountered. Thus, to
specify that the program starts at label START, the END statement
would be:

END START


11




If end-of-file is encountered on the source file before an
END statement is reached, the assembler will add an END statement
to the listing and flag it with a * (missing statement) error.



4.6 Pseudo-ops -- EQU

The EQU pseudo-op is used to assign a specific value to a
label, thus the label on this line is REQUIRED. Once the value
is assigned, it cannot be reassigned by writing the label in
column 1, by another EQU statement by a REG statement, or by a
SET statement. Thus, for example, the following statement
assigns the value 2 to the label TWO:

TWO EQU 1 + 1

The expression in the argument field must contain no forward
references.


4.7 Pseudo-ops -- IF, ELSE, ENDIF

These three pseudo-ops allow the assembler to choose whether
or not to assemble certain blocks of code based on the result of
an expression. Code that is not assembled is passed through to
the listing but otherwise ignored by the assembler. The IF
pseudo-op signals the beginning of a conditionally assembled
block. It requires one argument that may contain no forward
references. If the value of the argument is non-zero, the block
is assembled. Otherwise, the block is ignored. The ENDIF
pseudo-op signals the end of the conditionally assembled block.
For example:

IF EXPRESSION ;This whole thing generates
DB 01H, 02H, 03H ; no code whatsoever if
ENDIF ; EXPRESSION is zero.

The ELSE pseudo-op allows the assembly of either one of two
blocks, but not both. The following two sequences are
equivalent:

IF EXPRESSION
... some stuff ...
ELSE
... some more stuff ...
ENDIF

TEMP_LAB SET EXPRESSION
IF TEMP_LAB NE 0
... some stuff ...
ENDIF
IF TEMP_LAB EQ 0
... some more stuff ...
ENDIF


12




The pseudo-ops in this group do NOT permit labels to exist
on the same line as the status of the label (ignored or not)
would be ambiguous.


All IF statements (even those in ignored conditionally
assembled blocks) must have corresponding ENDIF statements and
all ELSE and ENDIF statements must have a corresponding IF
statement.

IF blocks can be nested up to 16 levels deep before the
assembler dies of a fatal error. This should be adequate for any
conceivable job, but if you need more, change the constant
IFDEPTH in file A51.H and recompile the assembler.


4.8 Pseudo-ops -- INCL

The INCL pseudo-op is used to splice the contents of another
file into the current file at assembly time. The name of the
file to be INCLuded is specified as a normal string constant, so
the following line would splice the contents of file "const.def"
into the source code stream:

INCL "const.def"

INCLuded files may, in turn, INCLude other files until four
files are open simultaneously. This limit should be enough for
any conceivable job, but if you need more, change the constant
FILES in file A51.H and recompile the assembler.


4.9 Pseudo-ops -- ORG

The ORG pseudo-op is used to set the assembly program
counter to a particular value. The expression that defines this
value may contain no forward references. The default initial
value of the assembly program counter is 0000H. The following
statement would change the assembly program counter to 0F000H:

ORG 0F000H

If a label is present on the same line as an ORG statement,
it is assigned the new value of the assembly program counter.


4.10 Pseudo-ops -- PAGE

The PAGE pseudo-op always causes an immediate page ejection
in the listing by inserting a form feed ('\f') character before
the next line. If an argument is specified, the argument
expression specifies the number of lines per page in the listing.
Legal values for the expression are any number except 1 and 2. A
value of 0 turns the listing pagination off. Thus, the following
statement cause a page ejection and would divide the listing into


13



60-line pages:

PAGE 60


4.11 Pseudo-ops -- REG

The REG pseudo-op functions like the EQU pseudo-op except
that the argument must be a register -- i.e. R0 - R7 or another
label defined with the REG pseudo-op. A label defined with REG
can be used anywhere that R0 - R7 is called for. This includes
forms like @LABEL. Like the EQU statement, the argument
expression must contain no forward references. A label defined
with the REG statement cannot be redefined by writing it in
column 1, by an EQU statement, by another REG statement, or by a
SET statement. The following pair of statements will assemble to
a "MOV @R0, A" instruction:

TEMP REG R0
MOV @TEMP, A


4.12 Pseudo-ops -- SET

The SET pseudo-op functions like the EQU pseudo-op except
that the SET statement can reassign the value of a label that has
already been assigned by another SET statement. Like the EQU
statement, the argument expression may contain no forward
references. A label defined by a SET statement cannot be
redefined by writing it in column 1 or with an EQU statement.
The following series of statements would set the value of label
"COUNT" to 1, 2, then 3:

COUNT SET 1
COUNT SET 2
COUNT SET 3


4.13 Pseudo-ops -- TITL

The TITL pseudo-op sets the running title for the listing.
The argument field is required and must be a string constant,
though the null string ("") is legal. This title is printed
after every page ejection in the listing, therefore, if page
ejections have not been forced by the PAGE pseudo-op, the title
will never be printed. The following statement would print the
title "Random Bug Generator -- Ver 3.14159" at the top of every
page of the listing:

TITL "Random Bug Generator -- Ver 3.14159"


5.0 Assembly Errors

When a source line contains an illegal construct, the line


14



is flagged in the listing with a single-letter code describing
the error. The meaning of each code is listed below. In
addition, a count of the number of lines with errors is kept and
printed on the C "stderr" device (by default, the console) after
the END statement is processed. If more than one error occurs in
a given line, only the first is reported. For example, the

illegal label "=$#*'(" would generate the following listing line:

L 0000 FF 00 00 =$#*'( LDA R0


5.1 Error * -- Illegal or Missing Statement

This error occurs when either:

1) the assembler reaches the end of the source file
without seeing an END statement, or

2) an END statement is encountered in an INCLude file.

If you are "sure" that the END statement is present when the
assembler thinks that it is missing, it probably is in the
ignored section of an IF block. If the END statement is missing,
supply it. If the END statement is in an INCLude file, delete
it.


5.2 Error ( -- Parenthesis Imbalance

For every left parenthesis, there must be a right paren-
thesis. Count them.


5.3 Error " -- Missing Quotation Mark

Strings have to begin and end with either " or '. Remember
that " only matches " while ' only matches '.


5.4 Error B -- Branch Target Out of Bounds

The 8051 relative branch instructions will only reach
addresses that are within -128 and +127 bytes of the first byte
of the next instruction. The 8051 absolute branch instructions
will only reach addresses on the same 2K page as the next
instruction. If this error occurs, the source code will have to
be rearranged to bring the branch target within range or a long
branch instruction that will reach anywhere will have to be used.


5.5 Error D -- Illegal Digit

This error occurs if a digit greater than or equal to the
base of a numeric constant is found. For example, a 2 in a
binary number would cause a D error. Especially, watch for 8 or


15



9 in an octal number.


5.6 Error E -- Illegal Expression

This error occurs because of:

1) a missing expression where one is required

2) a unary operator used as a binary operator or vice-
versa

3) a missing binary operator

4) a SHL or SHR count that is not 0 thru 15


5.7 Error I -- IF-ENDIF Imbalance

For every IF there must be a corresponding ENDIF. If this
error occurs on an ELSE or ENDIF statement, the corresponding IF
is missing. If this error occurs on an END statement, one or
more ENDIF statements are missing.


5.8 Error L -- Illegal Label

This error occurs because of:

1) a non-alphabetic in column 1

2) a reserved word used as a label

3) a missing label on a BIT, EQU, REG, or SET statement

4) a label on an IF, ELSE, or ENDIF statement


5.9 Error M -- Multiply Defined Label

This error occurs because of:

1) a label defined in column 1 or with the EQU statement
being redefined

2) a label defined by a SET statement being redefined
either in column 1 or with the EQU statement

3) the value of the label changing between assembly passes


5.10 Error O -- Illegal Opcode

The opcode field of a source line may contain only a valid
machine opcode, a valid pseudo-op, or nothing at all. Anything


16



else causes this error.


5.11 Error P -- Phasing Error

This error occurs because of:

1) a forward reference in a BLK, CPU, EQU, ORG, or SET
statement

2) a label disappearing between assembly passes


5.12 Error S -- Illegal Syntax

This error means that an argument field is scrambled. Sort
the mess out and reassemble. In particular, look for use of
registers that don't apply to a particular opcode, missing
commas, and the like.


5.13 Error T -- Too Many Arguments

This error occurs if there are more items (expressions,
register designators, etc.) in the argument field than the opcode
or pseudo-op requires. The assembler ignores the extra items but
issues this error in case something is really mangled.


5.14 Error U -- Undefined Label


This error occurs if a label is referenced in an expression
but not defined anywhere in the source program. If you are
"sure" you have defined the label, note that upper and lower case
letters in labels are different. Defining "LABEL" does not
define "Label."


5.15 Error V -- Illegal Value

This error occurs because:

1) an immediate value is not -128 thru 255, or

2) a direct address is not 0 thru 255, or

3) a bit expression contains an illegal address or bit
number, or

4) a DB argument is not -128 thru 255, or

5) an INCL argument refers to a file that does not exist.


6.0 Warning Messages


17




Some errors that occur during the parsing of the cross-
assembler command line are non-fatal. The cross-assembler flags
these with a message on the C "stdout" device (by default, the

console) beginning with the word "Warning." The messages are
listed below:


6.1 Warning -- Illegal Option Ignored

The only options that the cross-assembler knows are -l and
-o. Any other command line argument beginning with - will draw
this error.


6.2 Warning -- -l Option Ignored -- No File Name
6.3 Warning -- -o Option Ignored -- No File Name

The -l and -o options require a file name to tell the
assembler where to put the listing file or object file. If this
file name is missing, the option is ignored.


6.4 Warning -- Extra Source File Ignored

The cross-assembler will only assemble one file at a time,
so source file names after the first are ignored. To assemble a
second file, invoke the assembler again. Note that under CP/M-
80, the old trick of reexecuting a core image will NOT work as
the initialized data areas are not reinitialized prior to the
second run.


6.5 Warning -- Extra Listing File Ignored
6.6 Warning -- Extra Object File Ignored

The cross-assembler will only generate one listing and
object file per assembly run, so -l and -o options after the
first are ignored.


7.0 Fatal Error Messages

Several errors that occur during the parsing of the cross-
assembler command line or during the assembly run are fatal. The
cross-assembler flags these with a message on the C "stdout"
device (by default, the console) beginning with the words "Fatal
Error." The messages are explained below:


7.1 Fatal Error -- No Source File Specified

This one is self-explanatory. The assembler does not know
what to assemble.



18




7.2 Fatal Error -- Source File Did Not Open

The assembler could not open the source file. The most
likely cause is that the source file as specified on the command

line does not exist. On larger systems, there could also be
priviledge violations. Rarely, a read error in the disk
directory could cause this error.


7.3 Fatal Error -- Listing File Did Not Open
7.4 Fatal Error -- Object File Did Not Open

This error indicates either a defective listing or object
file name or a full disk directory. Correct the file name or
make more room on the disk.


7.5 Fatal Error -- Error Reading Source File

This error generally indicates a read error in the disk data
space. Use your backup copy of the source file (You do have one,
don't you?) to recreate the mangled file and reassemble.


7.6 Fatal Error -- Disk or Directory Full

This one is self-explanatory. Some more space must be found
either by deleting files or by using a disk with more room on it.


7.7 Fatal Error -- File Stack Overflow

This error occurs if you exceed the INCLude file limit of
four files open simultaneously. This limit can be increased by
increasing the constant FILES in file A51.H and recompiling the
cross-assembler.


7.8 Fatal Error -- If Stack Overflow

This error occurs if you exceed the nesting limit of 16 IF
blocks. This limit can be increased by increasing the constant
IFDEPTH in file A51.H and recompiling the cross-assembler.


7.9 Fatal Error -- Too Many Symbols

Congratulations! You have run out of memory. The space for
the cross-assembler's symbol table is allocated at run-time using
the C library function malloc(), so the cross-assembler will use
all available memory. The only solutions to this problem are to
lessen the number of labels in the source program or to add more
memory.



19


 December 7, 2017  Add comments

Leave a Reply