Sneaky Assembler Problem
One of our team had a problem with the way some assembler code was assembling. Basically an instruction was not assembling into the correct binary code.
As an Example, take the following Load Address instruction. The general form is:
Where R1 is the target register to receive the result, X2 in the source address index register, B2 is the source address Base register and D2 is a displacement that is added to the sum of the addresses in X2 and B2.
So if you coded say:
It would assemble into the following hex code:
If the index and base registers are both zero the instruction becomes:
Or you can write it as
Basically, this says put the number 9 into register 2. The hex code for it would resolve to:
However in their code, the same instruction (LA R2,9) was generating the following binary code:
It was as though they had coded:
A quick search up the listing showed that earlier on in the code the following line occured:
This should really not cause a problem since all it does (or so we thought) was to tell the assembler to use the value equated to the symbol R5 (as you might expect, the equated value is 5) as a base register whenever it encounters a field within the DSECT named NAME.
However, for reasons I will not go into here, we often do not map storage layouts using DSECTS but instead map them using equated values that define the offsets of the fields within the area. In this case NAME was at offset zero and so had been defined as:
NAME EQU X'0000'
On it’s own this is not a problem but when used in conjunction with the USING statement it has the effect (intentional or not, I am not sure) of assigning the value of the R5 equate (5 in this case) to IT’S equated value of zero, thus in effect telling the assembler to use the value 5 anywhere it would normally use a zero as the base register.
The motto of the story is to always review the generated assembler code as well as the source. It’s not always what you expect!