Disassembler Tutorial For DHC11
Disassembler Tutorial For DHC11
Disassembler Tutorial For DHC11
DHC11 Tutorial
This is a tutorial for the DHC11 Motorola 68HC11 Disassembler. Reference is also made to
the author's ASHC11, a 68HC11 Macro Assembler. The tutorial is heavily oriented to
disassembling a GM ECU binary (an EPROM found in a GM vehicle's ECU, or engine
management computer)
Text that you write is shown in red and console output that the disassembler produces is shown in dark blue
italics. File output that the disassembler produces is shown in normal dark blue.
Initially, the bin for disassembly (called BJKS8010.BIN in the examples) is identified and a control file BJKS is created
with the following minimal information describing the input file and the name of the output file.
; This control file is called BJKS
;
input bjks8010.bin ;this is the binary input file
output bjks.DIS ;this is the disassembly source/listing file
At a Dos prompt the command c:\>dhc11 bjks -a is given. The -a switch forces addresses in the output. The resulting
console output is shown below:
DHC11 - 68HC11 Disassembler v1.00 (c) Copyright 2000 Tech Edge Pty. Ltd.
This shows that the file was read into memory and automatically located from $8000 through to $FFFF. As no initial
entry point was supplied, the reset vector at $FFFE was used and this contained the address $9006. The first two passes
found 316 + 93 entry points, and the third found no more, so DHC11 stopped seeking more code and ran the code/data
output pass.
Looking at the output file bjks.dis we find there is a lot of data that should probably be code. We remember that the
68HC11 has a few vectors at the top of memory. Inspecting the file we see:
This indicates that there are probably 8 vectors. The easiest way to tell the disassembler this is via the control file line:
vectors $fff0 8 hc11vec hc11vector
Doing this, and running DHC11 again, but this time with the -ov switch to overwrite the old output file bjks.dis, we get
the following
** Symbol "hc11vec_00" is already Install at $6000 ("hc11vec_03" requested)
Entry point $1000 outside ROM image (ref. from PC = $916E).
Indexed Call/Jump at $94BB, may require a vector table.
Entry point $1009 outside ROM image (ref. from PC = $94CC).
Indexed Call/Jump at $D20A, may require a vector table.
Indexed Call/Jump at $D3A2, may require a vector table.
Pass 1 found 1466 new entry points.
Pass 2 found 132 new entry points.
Pass 3 found 3 new entry points.
Pass 4 found 0 new entry points.
Total of 4 iteration(s) to find all code.
We now find more code (1466 + 132 + 3 entry points) and it takes an extra pass. We also find we now have two messages
indicating indexed call instructions were encountered. Looking at the code for the two address ($D20A and $D3A2) we
find the code:
D1EA LD1EA ldaB L01BE
D1ED cmpB #$0A
D1EF bhi LD235
D1F1 bset L005E, #%00100000
D1F4 bset L005D, #%00000100
D1F7 staB L01B9
D1FA lslB
D204 ldX #$D249
D207 aBX
D208 ldX 0, X
D20A call 0, X
.... ...
;
D39E LD39E ldY L01B2
D3A2 call 0, Y
The first indexed call is easy, as the address of a table (at $D249 is supplied, and it looks like there are only 11 entries
(register B is compared against $0A and branches if higher, so 0..10 => 11) Also, knowing a bit about the application, we
may know that some code is called at fixed time intervals from a timer interrupt, and calls successive procedures listed in
a table. So we can add the command:
vectors $D249 11 loop timevectors
Forgetting about the second indexed call for the moment, we run DHC11 again and find another indexed call
Indexed Call/Jump at $94BB, may require a vector table.
And again we look at the code and discover a vector table at $94DB, and it seems to have 16 entries as the code shows
register B is masked to a 4 bits (= 16 entries):
94B2 andB #%00001111 <-- mask to 4 bits here 94B4 ldX #$94DB <-- base table address here 94B7 lslB 94B8 aBX
94B9 ldX 0, X 94BB call 0, X <-- call one of 16 address So, not being sure what these vertors are for, we add the
following command and run DHC11 again:
vectors $94db 16 some somevectors
We don't get any more indexed jumps, but we now have (2138 + 130 + 3 = 2271) entry points being automatically found.
So, we look through the code generated by DHC11 and we find a large slab of dbs at $cbc3, so wee look through the
code for references to this address and we find this adress is used as a parameter in a call:
C2DF LC2DF ldX #$CBC3 <-- load here
C2E2 brset L0059, #%00000100, LC2EF
C2E6 brset L0074, #%00100000, LC2EF
C2EA ldX #$CBD4
C2ED jr LC2F5
;
C2EF LC2EF addA #$0A
C2F1 bcc LC2F5
C2F3 ldaA #$FF
C2F5 LC2F5 call LC9B5 <-- call here
Looking through the code for the call's target address of $c9b5 we find many calls to this address using the IX register as
a parameter. Looking at the code at $c9b5 we find some kind of a table looup routine. Now, here's where we could slog it
out and try to work out what's happening, but a few people have already done some of the hard work, including ECMguy
at http://ecmguy.tripod.com/, whos disassembly of the BUA binary can be found (in text format) at:
ftp://ftp.diy-efi.org/incoming/Bua_hac_text.zip
A quick (!) look at the BUA disassembly will show that a possible name for the function at $C9B5 could be P4LKUPQ.
We'll choose the label Lookup2d16 (remembering that most assemblers would not like a label starting with a number)
because it better reflects its function, and we are not limited to a certain number of characters for our labels. We'll also
add a few more labels we can assign just by looking at the BUA disassembly and comparing code around the
Lookup2d16 area.
entry $c9aa Lookup2d_nooff ;2D Lookup with offset
entry $c9b1 Lookup2d ;2D Lookup
entry $c9b5 Lookup2d16 ;2D Lookup with tables spaced at 16
entry $c9c9 Interpol ;interpolate between two 8 bit values
entry $c9d2 Lookup3d ;3d Lookup (2 variables)
entry $ca74 mul16x16 ;multiply 16 x 16
We could spend a bit of time comparing routines and assigning labels for those routines that are common. For the case
where we know a bit about the software or hardware, but don't have a disassembly to help, we must do some more
investigation. The ALDL data stream can help us. The ALDL output of most ECMs is reasonably well documented, so
we need to look for the ALDL code to help us identify the location, in memory, where the data is stored. This may give
us the memory locations for many variables and tables.
Statistics by www.digits.com
Shows approximate hits since 15 May 2000.