Help with 68k assembly - jump tables?
Asked Answered
S

1

11

I'm working on reverse engineering a large Amiga program in IDA, and I've made a ton of progress. However, there is some stuff I can't quite figure out. Namely, I have found several subroutines which use what I believe to be "jump tables" - but I can't quite figure out how they work. Does anyone have any advice?

        moveq   #0,d0
        move.b  d7,d0       ; set D0 to a byte from CTRL
        subq.w  #1,d0       ; subtract 1 from it
        blt.w   finish_29ABA    ; if D0 is less than 1, branch
        cmpi.w  #$16,d0
        bge.w   finish_29ABA    ; if D0 is greater than or equal to 16, branch
        add.w   d0,d0       ; otherwise, double D0
        move.w  dword_29918(pc,d0.w),d0
        jmp dword_29918+2(pc,d0.w)
; ---------------------------------------------------------------------------
dword_29918:    dc.l $400036        ; CODE XREF: serialCtrlCmd+E0j
        dc.l $360036
        dc.l $3601A0
        dc.l $3601A0
        dc.l $1A001A0
        dc.l $360040
        dc.l $2A01A0
        dc.l $400036
        dc.l $3601A0
        dc.l $1A00036
        dc.l $1A00036
        dc.l $33FC0003
        dc.l HEAP_3B897+$41A7   ; CTRLRead3
; ---------------------------------------------------------------------------
        bra.w   finish_29ABA
; ---------------------------------------------------------------------------
        tst.w   (CTRL_36494).l
        bne.w   return_29AF6
        moveq   #1,d0
        lea ((HEAP_3B897+$2665)).l,a0
        adda.w  (CTRLRead1).l,a0
        move.b  d7,(a0)
        moveq   #0,d1
        move.b  d7,d1
        move.w  d1,(CTRLRead2).l
        move.w  (CTRLCmds).l,d1
        addq.w  #1,d1
        move.w  d1,(CTRLCmds).l ; Increment CTRL Cmds by 1
        move.w  d0,(CTRLRead3).l
        bra.w   finish_29ABA
Shererd answered 30/6, 2011 at 16:58 Comment(3)
Is IDA the only disassembler for 68k?Endotoxin
There are plenty, but most of the ones I've found are for the Amiga platform itself. I'm sure there are several others.Shererd
Keep in mind that the bulk of code for the Amiga was written to be entirely "relocatable". Using jump tables was pretty much a standard (even for system libraries). The program loader would "relocate" all fixed addresses (a safe operation because there is no virtual memory management), and then all jumps/references were done as offsets.Holm
H
18
    blt.w   finish_29ABA    ; \
    cmpi.w  #$16,d0         ; > These insns check that the index is in range
    bge.w   finish_29ABA    ; /

    add.w   d0,d0           ; since the jump table contains words,
                            ; multiply the index by 2, to get a word index

    move.w  dword_29918(pc,d0.w),d0 ; get a word from the jump table, indexed by d0

    jmp dword_29918+2(pc,d0.w)      ; perform an indirect jump to (PC,d0)

    dword_29918:            ; the following are offsets encoded as words
      ; 0040 0036 0036 0036...

This is usually the result of a C switch statement.

Howlyn answered 30/6, 2011 at 19:56 Comment(3)
Thank you very much, that was extremely helpful. Everything also makes much more sense when the data is interpreted as words.Shererd
@Mikaveli, yes, niche, but a pretty large niche. We are many sleeper Amigans out there. :-)Braid
The offsets being written as dc.l was throwing me at first :) In my own code I have used direct address jump tables.Regiment

© 2022 - 2024 — McMap. All rights reserved.