MultiMIPS 8051 Relocator
The Relocator is an MS Visual Basic program which relocates standard Intel format HEX
files so that they can be loaded at alternate 8051 program memory addresses.
It is not always possible to relocate a program in HEX file format to an arbitrarily chosen
load address. There are three parts of the process with which the program requires
assistance. For these parts it is helpful if the user has some of the following knowledge:
the Intel HEX file format
the content of the particular HEX file
counting and adding of hexadecimal numbers
the software used to create the HEX file
the coding techniques used by the original programmer of the software
Some trial and error may be necessary to get as close as possible to the desired load
address. Take an analytical approach: write down a list of the specific problem areas and
keep careful notes on the trials. This may be a tedious process, but it is not one that is
difficult. The Relocator program does provide some assistance, as do the instructions and
other information in this document.
In particular, the three problem areas are:
1. MOV DPTR,#data16
2. AJMP and ACALL
3. Constants
Intel HEX File Format
The machine language is stored in ASCII code, hexadecimal representation. It can be
viewed [and even altered] with any text editor such as Windows NotePad. Each line of
the file is independent of the others. This means that the lines can be arbitrarily reordered
without introducing errors. It also means that a HEX file can be broken up by line into
parts with a text editor, the parts can be worked with separately, and the file then put back
together again. This may be a useful technique when, for example, dealing with the
section of the file that contains constants rather than machine language.
The format is as follows:
Column
Numbers
Contents
Comments
1
Colon
First character in position 1 of each
line
2 - 3
Number of
Bytes
of machine language beginning in
column 10
4 - 7
Load Address
for 1st byte of machine language in
column 10
8 - 9
Record Type
00 for machine language, 01 for end of
file
10 - Last-2
Machine
Language
2 columns is 1 byte of machine
language
Last 2
Check Sum
[Hex 0100 minus [Sum AND HEX
00FF]]
This example is part of the HEX file for an early version of the MultiMIPS
Operating System Kernel. All of the data are hexadecimal.
:06432E0003050003060177
:030000000240EECD
:03001B00024000A0
:0300230002400E8A
:0E400000D2ABD53008D53105753130B29032D3
:10400E00C0D0C0E0C000C0F0C083C08210991410B0
:10401E0098310240EED082D083D0F0D000D0E0D0E4
:10402E00D02232D53C0B853D83853E82E412403052
:10403E0073A83B869908E8B43A027832883B12405E
:03404E003080D2ED
:00000001FF
Each line begins with a colon in column 1.
Columns 2 and 3 contain a hexadecimal number representing the number of bytes of
machine language or constant data beginning in column 10. Line 1 has 6 [0x06] bytes:
03, 05, 00, 03, 06, and 01. Line 5 has 14 [0x0E] bytes: D2, AB, D5, 30, 08, D5, 31, 05,
75, 31, 30, B2, 90, and 32. Lines 6 through 9 each have 16 [0x10] bytes.
Columns 4 through 7 contain the load address for the byte in column 10. The subsequent
bytes on the line, except for the check sum, are loaded into the sequentially following
addresses. For the second last line, 30 is loaded into address 0x404E, 80 is loaded into
address 0x 404F, and D2 is loaded into address 0x4050.
Each line has 00 in columns 8 and 9 except for the last line, which has 01 marking it as
end of file.
The last 2 columns of each line contain a check sum. This is the sum of all of the other
bytes on the line, ANDed with 0x00FF, and subtracted from 0x0100. For example, for the
second-last line:
ED = 0100 - [[03 + 40 + 4E + 00 + 30 + 80 + D2] AND 00FF]
MOV DPTR,#data16
It is not practical for a utility program to determine whether to relocate the operand of
MOV DPTR,#data16. If DPTR will be used by JMP @A+DPTR then #data16 must be
relocated. If it will be used by MOVC A,@A+DPTR then it probably must be relocated.
If it will be used by MOVX @DPTR,A then it probably must not be relocated. It is
possible also that a "clever" programmer is loading the two registers DPH and DPL with
data using this one instruction.
When the MultiMIPS 8051 HEX Relocator program finds MOV DPTR,#data16 in the
machine language, it asks the user to decide whether to relocate #data16 or not. The
correct procedure in each case can be determined by examining the machine language
code. More simply, if the #data16 value falls within the same range as the load addresses,
it probably needs to be relocated. This may be a trial and error situation.
AJMP and ACALL
If the program is to be relocated by a multiple of 2K bytes then AJMP and ACALL
instructions will automatically relocate with no problems. But it is not always possible to
relocate the operand of these instructions to an arbitrarily chosen load address.
When the MultiMIPS 8051 HEX Relocator program finds AJMP or ACALL in the
machine language, it attempts to relocate the operand. If it is not successful, it displays a
message containing the numeric information needed to effect a successful relocation.
This may again be a trial and error situation, as there may be several AJMPs or ACALLs
with conflicting needs, and the corrections required may conflict with other AJMPs or
ACALLs.
The two items of numeric information displayed are the load address for the AJMP or
ACALL instruction, and the operand address. The requirement is that these two addresses
be within the same fixed address 2K [0x800 or 2048 decimal] block of memory as is the
first byte of the instruction following the ACALL or AJMP.
The procedure to follow is:
1. Determine the load address of the ACALL or AJMP from the message displayed
by the Relocator.
2. Determine the load address of the following instruction by adding 2, using
hexadecimal arithmetic.
3. Determine the operand address from the message displayed by the Relocator.
4. Determine the address of the boundary between the load address block and the
operand address block
5. Compute the absolute difference between the boundary and the operand address.
6. Adjust your "relocate to" address by this quantity using hexadecimal arithmetic.
For example, the Relocator program may output the message:
Unable to Relocate AJMP or ACALL
773A : 7804
0x773A + 2 = 0x773C is the load address for the next instruction after the AJMP or
ACALL; it is in the 2K block beginning at 0x7000. 0x7804 is the operand address; it is in
the 2K block beginning at address 0x7800. The "relocate to" address must in this case be
moved back toward zero by 5 bytes so that the operand address will compute to 0x77FF,
and consequently be in the same 2K block as the load address of the instruction following
the AJMP or ACALL.
Constants
In the example given above, the constants are represented in line 1 of the file.
:06432E0003050003060177
We must determine the location in the HEX file of the program constants so that we can
omit them from the relocation process, except that their load address must be relocated. It
is not practical for a utility program to distinguish between constants and machine
language instructions in the HEX file format. It is possible though for a person to make
this distinction, provided the person has some knowledge of the language translator
[assembler or compiler, and linker] used to prepare the HEX file, the Intel HEX file
format, and the particular HEX file itself. The Relocator displays the HEX file contents
and allows it to be sorted to assist the user with this part of the process. There are two
things the user can do.
First, locate the constants generally within the HEX file. Where the constants are located
depends on coding techniques used by the programmer, and on the language translator
used to produce the HEX file. The constants may be grouped into one place in the file,
possibly at the beginning, and possibly in one or a few contiguous lines. The given
example is part of a HEX file produced by the MicroVision Bitware RainBolt Keil
Assembler and Linker. The programmer used assembler directives rather than absolute
addresses to organize the program.
Second, interpret the machine language as would an 8051 microcontroller. If the result
makes no sense then it may well be the program constants rather than machine language.
For this it is helpful to have at hand a reference such as Intel order number 272383-002,
MCS51 Microcontroller Family User's Manual, especially pages 2-25 to 2-27. This is not
a difficult process, although it can be quite tedious, and you must take care to begin with
the operation code of a machine language instruction, and not with part of an operand.
For example, in line 3:
:03001B00024000A0
columns 10 and 11 contain 02, the machine language operation code for LJMP. This is a
3-byte instruction. The next 2 bytes 4000 are the operand, in this case the address to
LJMP to.
In line 5:
:0E400000D2ABD53008D53105753130B29032D3
Columns 10&11: D2 is SETB, a 2-byte instruction with operand AB in columns 12&13.
Columns 14&15: D5 is DJNZ, a 3-byte instruction with operand 3008 in columns 16 to
19
Columns 20&21: D5 is DJNZ, a 3-byte instruction with operand 3105 in columns 22 to
25
Columns 26&27: 75 is MOV, a 3-byte instruction with operand 3130 in columns 28 to 31
Columns 32&33: B2 is CPL, a 2-byte instruction with operand 90 in column 34
Columns 35&36: 32 is RETI, a 1-byte instruction with no operands.
Columns 37&38: D3 is the check sum.
Sometimes a machine language instruction overlaps two lines. In lines 6 and 7:
:10400E00C0D0C0E0C000C0F0C083C08210991410B0
:10401E0098310240EED082D083D0F0D000D0E0D0E4
The machine language instruction 10 JBC, a 3-byte instruction with operand 9831, begins
at the end of line 6 before the checksum B0, and continues at the beginning of line 7 after
the record type 00.
If we interpret line 1 we get:
:06432E0003050003060177
03 is RR, a 1-byte instruction
05 is INC, a 2-byte instruction with operand 00
03 is RR, a 1-byte instruction
06 is INC, a 2-byte instruction with operand 01
77 is the checksum
Regarding line 1, the question to be answered is, does this last sequence make sense in
the context of this program at memory address 432E? It helps in this case to know that,
with the language translator and coding techniques used, the constants are located at the
highest addresses of the program, and at the beginning of the HEX file.