XTRAN Example — Translate In-line Function Arguments in Encore (SEL, Gould) Assembler
In some assemblers, you can code a "branch and link" instruction followed by in-line arguments in the form of data operators. The called function advances the Program Counter past the in-line arguments before returning. Encore assembler offers an example of this technique.
We have developed a standard set of rules for handling this situation when translating from such an assembler to C. The rules comprise 88 non-comment lines of XTRAN's rules language (which we call "meta-code"). They are almost assembler-independent, and therefore easily tailored for a particular assembler. They direct XTRAN to do the following things:
Before translation, find all such in-line argument data operators and mark
them "do not translate" so they won't come out in the C code
resulting from translation
When translating each "branch and link" instruction
For each in-line data operator following the instruction, if any
Add its operands to an argument list we create for the call
If it has comments, add them to the "branch and link"
instruction so they will be preserved through translation
Translate the instruction to a function call with the argument list (if
any) we have generated from the in-line data operators following the
instruction
The following example uses a standard set of XTRAN rules for parsing Encore assembler and translating it to C, plus the standard rule set described above for handling in-line function arguments. NOTE that the translation shown below was done with default conditions. XTRAN provides many options for controlling the way it translates.
Process Flowchart
Here is a flowchart for this process, in which the elements are color coded:
- BLUE for XTRAN versions (runnable programs)
- ORANGE for XTRAN rules (text files)
- RED for
code
Input to XTRAN:
WRD1 REZ 1W WRD1 REZ 1W
START BL FUNC1 BL FUNC1
DATAW 1 DATAW 1
DATAW 2 DATAW 2
LW 1,WRD1 LW 1,WRD1
BL FUNC2 BL FUNC2
DATAW 1
BL FUNC2 BL FUNC2
LW 1,WRD1 LW 1,WRD1
Output from XTRAN:
extern long r1;
extern unkn func1;
extern unkn func2;
long wrd1 = 0; /*wrd1 rez 1w*/
start:
func1(1, 2); /*bl func1*/
/*dataw 1*/
/*dataw 2*/
r1 = wrd1; /*lw 1,wrd1*/
func2(1); /*bl func2*/
func2(); /*bl func2*/
r1 = wrd1; /*lw 1,wrd1*/