帮助处理68k汇编 - 跳转表?

11

我正在使用IDA对一个大型Amiga程序进行反向工程,并取得了很多进展。然而,有些东西我无法完全理解。具体来说,我发现了几个使用我认为是“跳转表”的子程序,但我无法弄清楚它们是如何工作的。请问有人有什么建议吗?

        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

IDA是68k唯一的反汇编器吗? - user502187
有很多,但我发现大部分都是针对Amiga平台本身的。我相信还有其他几个。 - AriX
2
要记住的是,Amiga的大部分代码都是为了完全“可重定位”而编写的。使用跳转表几乎是标准做法(即使对于系统库也是如此)。程序加载器会“重定位”所有固定地址(这是一种安全操作,因为没有虚拟内存管理),然后所有跳转/引用都以偏移量形式执行。 - Avery Payne
1个回答

19
    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...

这通常是C语言switch语句的结果。


非常感谢,那真的非常有帮助。当数据被解释为单词时,一切也更加清晰明了。 - AriX
5
@Mikaveli,没错,是一个小众市场,但这个市场还是相当大的。我们有许多隐藏的Amiga爱好者存在。 :-) - Prof. Falken
一开始,dc.l 写入的偏移量让我有些困惑 :) 在我的代码中,我使用了直接地址跳转表。 - Graeme

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接