REXX Language implementation
A disassembler reverses the actions of an assembler; where the assembler turns a text file containing instructions and directives into a binary executable, the disassembler returns this binary file into its text form\footnote{as much as possible, given the fact that some information on literals has disappeared};in this case it delivers a disassembly which in itself can be re-assembled - and still works.
The \code{rxdas} disassembler has a \code{.rxbin} file as input and produces a text file as output which goes to \code{stdout}. In this text file a disassembly has taken place; labels are synthetic and based on the combination of instructions around them. As clearly can be seen in the above, the labels generated by the \crexx{} compiler are not the same as the ones generated by the disassembler. With option \code{-p}, the constant pool of the \code{.rxbin} file is printed first, before the rest of the disassembly.
The current \code{003} \code{.rxbin} format is fully supported, including pooled float literals, packed code and constant sections, and the interface/class metadata directives \code{.class}, \code{.attr}, \code{.interface}, \code{.implements}, and \code{.member}.
When the command line argument -h is specified the options are shown:
\fontspec{IBM Plex Mono}
\begin{shaded}
\small
\obeylines \splice{rxdas -h | sed “s/&/\and/g”}
\end{shaded}
\fontspec{TeX Gyre Pagella}
```rexx /* compute sum of numbers 1 to 100 (5050) / options levelb / compute sum of numbers 1 to 100000 */ sum = 0 do i=1 to 100000 sum = i+sum end say “the sum of the numbers 1 to 100000 is:” sum return
This program, when compiled by the 'rxc' compiler, produces the following assembly source:
```rxas <!--sumloop.rxas-->
/*
* cREXX COMPILER VERSION : cREXX F0044
* SOURCE : sumLoop1000.rexx
* BUILT : 2023-03-03 23:56:03
*/
.srcfile="sumLoop1000.rexx"
.globals=0
main() .locals=4
.meta "sumloop1000.rexx.main"="b" ".void" main() ""
.src 4:1="sum = 0"
.meta "sumloop1000.rexx.main.sum"="b" ".int" r1
load r1,0
.src 5:1="do"
.src 5:4="i=1"
.meta "sumloop1000.rexx.main.i"="b" ".int" r2
load r2,1
.src 5:8="to 100000"
load r3,100000
l7dostart:
.src 5:8="to 100000"
igt r0,r2,r3
brt l7doend,r0
.src 6:4="sum = i+sum"
iadd r1,r2,r1
l7doinc:
.src 5:4="i"
inc r2
.src 7:1="end"
br l7dostart
l7doend:
.src 8:1="say \"the sum of the numbers 1 to 100000 is:\" sum"
itos r1
sconcat r3,"the sum of the numbers 1 to 100000 is:",r1
say r3
.src 9:1="return"
ret
.meta "sumloop1000.rexx.main.i"
.meta "sumloop1000.rexx.main.sum"
The assembler produces an ‘rxbin’ file from that. What follows is the disassembly from this ‘rxbin’ file.
```rxas
DESCRIPTION - sumLoop1000
CONSTANT POOL - Size 0x7c0. Dump of EXPOSED entries only (option -p not used):
.globals=0 .srcfile=”sumLoop1000.rexx”
main() .locals=4 .meta “sumloop1000.rexx.main”=”b” “.void” main() “” .src 4:1=”sum = 0” .meta “sumloop1000.rexx.main.sum”=”b” “.int” r1 load r1,0 * 0x000000:00c3 Load op1 with op2 .src 5:1=”do” .src 5:4=”i=1” .meta “sumloop1000.rexx.main.i”=”b” “.int” r2 load r2,1 * 0x000003:00c3 Load op1 with op2 .src 5:8=”to 100000” load r3,100000 * 0x000006:00c3 Load op1 with op2 .src 5:8=”to 100000” lb_9: igtbr lb_14,r2,r3 * 0x000009:0066 Int Greater than if (op2>op3) goto op1 .src 6:4=”sum = i+sum” iadd r1,r2,r1 * 0x00000d:0001 Integer Add (op1=op2+op3) .src 5:4=”i” .src 7:1=”end” bctp lb_9,r2 * 0x000011:00f4 inc op2; goto op1 .src 8:1=”say "the sum of the numbers 1 to 100000 is:" sum” lb_14: itos r1 * 0x000014:00d9 Set register string value from its int value sconcat r3,”the sum of the numbers 1 to 100000 is:”,r1 * 0x000016:0040 String Concat with space (op1=op2||op3) say r3 * 0x00001a:00cb Say op1 .src 9:1=”return” ret * 0x00001c:00a1 Return VOID .meta “sumloop1000.rexx.main.i” .meta “sumloop1000.rexx.main.sum” ```
This file has the output of the disassembler; the procedure name, \code{main}, is identical, but the first label generated by the compiler, \code{l7dostart:} is called \code{lb_9} in the disassembler output. This is of no consequence for a subsequent re-assembly and execution of the program.
Do note that the lines are longer than expected, because every disassembled line has the binary representation and a standard explanation of the generated instruction. This makes it easier to find back instructions in an .rxbin load module.
The instructions, however, can be different than expected due to the optimizations the assembler performs. When the compiler has performed optimizations, this is already visible in the \code{.rxas} file. The assembler optimizations are visible in the disassembled object.
The standard instruction documentation the disassembler affixes is the same as displayed by the rxas -i command, in a line comment after the instructions and their operands.
When stepping through a program using the \crexx{} Debugger (which is
mentioned in the next chapter), the disassembly is the most
representative record of what is in the .rxbin executable.