Forum: Compiler & IDEs HCS12 Assembler lesen/interpretieren


von Olli Z. (z80freak)


Lesenswert?

Hallo,

ich versuche mich gerade am Reverse-Engineering von HCS12 Assembler und 
würde mich sehr freuen ein wenig Starthilfe zu bekommen :-)

Zunächst scheint die CPU mit ihren fünf 16-Bit Registern und dem CCR 
sehr übersichtlich zu sein, im Vergleich zu einer ARM-Basierenden, es 
gibt aber dennoch einen großen Befehlssatz. Ich habe in meiner Jugend 
(schwelm) mal Assembler auf einer Z80 CPU programmiert, das war 
vergleichbar, ist aber schon so lange her das ich fast alles vergessen 
habe.

Zum üben habe ich mir eine ISR aus dem Dump eines Fahrzeugmoduls auf dem 
ein MC9S12DG werkelt ausgesucht um herauszufinden was die letztendlich 
macht und wie. Die ISR wird nach dem Empfang einer CAN-Botschaft 
ausgelöst. Eine ISR hat ja keine Parameter, d.H. sie muss alles was sie 
benötigt aus der Umgebung (RAM, ROM) ziehen. Auch sollte eine ISR ja 
möglichst kurz sein, was mich zur Annahme verleitet das hier die 
empfangene Nachricht nur woanders abgelegt wird und über eine Semaphore 
das Signal gesetzt wird das damit etwas geschehen soll.

Ich habe mir erstmal angeschaut worauf der Code alles zugreift. Das sind 
neben den Registern des Chips natürlich Speicherstellen im RAM. Im (mir 
nicht verfügbaren) Quellcode sind diese sehr wahrscheinlich als 
"volatile" deklariert. Der Rest ist Zeiger- und Register-Arrithmetik. 
Die Kommentare im folgenden Listing stammen größtenteils von mir, sind 
also potentiell falsch ;-)
1
ROM_HI:C34D _CAN0_receive:                          ; DATA XREF: USER_VEC:FFB2↓o
2
ROM_HI:C34D                 leas    -3,sp           ; Load effective address into SP
3
ROM_HI:C34F                 brset   byte_FSR_3161,#0x10,loc_ROM_HI_C386 ; Ignore remote frames (RTR Bit set)
4
ROM_HI:C354                 ldab    CAN0IDAC        ; load "MSCAN Identifier Acceptance Control Register" into B
5
ROM_HI:C357                 andb    #7              ; mask out by bits found at 0x0007
6
ROM_HI:C359                 stab    2,sp            ; push B to stack index 2
7
ROM_HI:C35B                 ldd     #3              ; load D (A,B) from 0x0003 ...
8
ROM_HI:C35E                 std     0,sp            ; ... and push to stack
9
ROM_HI:C360
10
ROM_HI:C360 loc_ROM_HI_C360:                        ; CODE XREF: _CAN0_receive+28↓j
11
ROM_HI:C360                 ldd     0,sp            ; D = SP[0]
12
ROM_HI:C362                 lsld                    ; D = D * 2
13
ROM_HI:C363                 tfr     d,y             ; Y = D
14
ROM_HI:C365                 ldd     CAN0RXFG        ; D = [CAN-ID]
15
ROM_HI:C368                 andb    #0xF8           ; D:0-7 (=B) AND 0b1111 1000
16
ROM_HI:C36A                 cpd     -0x3B7,y        ; Compare D to memory (16-bit)
17
ROM_HI:C36E                 beq     loc_ROM_HI_C377 ; Branch if equal
18
ROM_HI:C370                 ldy     0,sp            ; Load Y
19
ROM_HI:C372                 dey                     ; Decrement Y
20
ROM_HI:C373                 sty     0,sp            ; SP[0] = SP[0] - 1
21
ROM_HI:C375                 bge     loc_ROM_HI_C360 ; while A >= 0
22
ROM_HI:C377
23
ROM_HI:C377 loc_ROM_HI_C377:                        ; CODE XREF: _CAN0_receive+21↑j
24
ROM_HI:C377                 ldy     0,sp            ; Load Y
25
ROM_HI:C379                 blt     loc_ROM_HI_C386 ; if a < 0
26
ROM_HI:C37B                 ldab    -0x3AF,y        ; Load B
27
ROM_HI:C37F                 clra                    ; Clear A
28
ROM_HI:C380                 std     0,sp            ; Store D
29
ROM_HI:C382                 call    sub_ROM_HI_C38E,#3 ; Call subroutine in expanded memory
30
ROM_HI:C386
31
ROM_HI:C386 loc_ROM_HI_C386:                        ; CODE XREF: _CAN0_receive+2↑j
32
ROM_HI:C386                                         ; _CAN0_receive+2C↑j
33
ROM_HI:C386                 ldab    #1              ; Load B
34
ROM_HI:C388                 stab    CAN0RFLG        ; ACK received CAN-Message (load next from buffer)
35
ROM_HI:C38B                 leas    3,sp            ; restore stack
36
ROM_HI:C38D                 rti                     ; Return from interrupt
37
ROM_HI:C38D ; End of function _CAN0_receive

von MaWin (Gast)


Lesenswert?

Ja, du bist auf dem Holzweg.

LEAS -3SP bait ein Stackframe für 3 byte fur funktionslokale Variablen 
auf, so wie in
1
interruptfunction()
2
{
3
  word idac;
4
  char cnt;
5
6
  idac =*(word *)CAN0IDAC;
7
  cnt=3;

Es wird bei STAB nicht gepusht, sondern ein word dort hin gespeichert. 
Und eine 3 in die char Variable davor.

PUSH heisst, dass der SP dabei verändert wird. Wird er bei STAB nicht.

von Olli Z. (z80freak)


Lesenswert?

"leas -3,sp"

Das ist doch eine Stackpointer-Manipulation, oder? Dabei wird dann im 
Enteffekt die aktuelle im Stackpointer hinterlegte Adresse um 3 
verringert, also wie "SP = SP - 3". Also wenn "SP = 0x1FF8" wäre, dann 
wäre er nach "leas -3,sp" "SP = 0x1FF5".
Also anstelle einer push Operation mit Dummywerten wird dort einfach für 
3 Byte "Platz" vom Stack gesichert, welcher sich ja auch im RAM 
befindet.

"brset   byte_FSR_3161,#0x10,loc_ROM_HI_C386"
müsste dann soviel bedeuten wie:
if( *(byte_FSR_3161) & 0x10 != 0) {
  // handle non remote CAN frames (RTR not set)
}
:loc_ROM_HI_C386

Das hier ist doch ganz klar eine loop:
1
ldd     #3              ; D = 3
2
std     0,sp            ; *(SP) = D
3
4
loc_ROM_HI_C360:
5
ldd     0,sp            ; D = *(SP)
6
lsld                    ; D = D * 2 // vermutlich ein offset in einem word-array
7
tfr     d,y             ; Y = D
8
ldd     CAN0RXFG        ; D = *(CAN0RXFG) // CAN-ID
9
andb    #0xF8           ; D = D & 0b00000000 11111000
10
cpd     -0x3B7,y        ; // vergleiche die CAN-ID mit der in dem Array
11
beq     loc_ROM_HI_C377 ; BREAK // bei Übereinstimmung verlasse die loop
12
ldy     0,sp            ; Y = *(SP)
13
dey                     ; Y = Y -1
14
sty     0,sp            ; *(SP) = Y
15
bge     loc_ROM_HI_C360 ; while *(SP) >= 0
16
17
loc_ROM_HI_C377:
18
...
Sieht für mich so aus als wäre die Zählervariable (nennen wir sie mal 
"i") hier auf SP[0] also am Fuß des Stacks.

von Erich (Gast)


Lesenswert?

Olli Z. schrieb:
> Reverse-Engineering von HCS12 Assembler

Das macht keinen Spaß.
Es sind unheimliche viele teils merkwürdige Addressierungsarten möglich.
Z.B. indirekt indiziert, wahrscheinlich auch mit 8 oder 16 Bit Offset.
Was ich noch erinnere: Akkus A, B können multipliziert werden nach D. 
Aber so eine Addition (oder gar Subtraktion) gibt es nicht.
Gruss

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.