6502汇编代码中高效多重间接寻址的实现与优化
问题提出
我正在分析一段6502架构程序,其中包含多组长度不等的字节数组(对应不同声道的音效数据)。当前实现需要显式遍历已入队的第一组、第二组……数据,且每个声道都配有独立的音量、延迟等变量,代码全部使用硬编码标签编写。
我希望将这部分逻辑重构为循环结构,通过索引访问上述附属变量与音效数据。使用索引寻址方式访问变量的实现较为简单,但索引访问音效数据需要额外消耗大量运算,我想确认自己是否在索引间接寻址、间接索引寻址方式的应用上存在遗漏。
以下是我当前实现的完整可运行示例,我希望尽可能优化LoadFromTable部分的代码,最好能同时结合X、Y寄存器的寻址能力:
.equ Ptr0, 0x80 .equ Ptr1, 0x81 .org 0xFE00 .org 0x0000 Init: LDX #0xFF TXS Main: LDX #0x00 LDY #0x00 JSR LoadFromTable ; A should be 'H', 0x48 LDX #0x01 LDY #0x00 JSR LoadFromTable ; A should be 'B', 0x42 LDX #0x02 LDY #0x02 JSR LoadFromTable ; A should be 'A', 0x41 JMP Main LoadFromTable: TXA ; Double outer index to account for 16 bit pointers ASL ; " TAX ; " LDA Table,X ; Load the low byte of the array into a pointer STA Ptr0 ; " INX ; Load the high byte of the array into the pointer LDA Table,X ; " STA Ptr1 ; " LDA (Ptr0),Y ; Load the character at the inner index into the array RTS .org 0x0040 Table: .word Item0 .word Item1 .word Item2 .org 0x0080 Item0: .byte 'H', 'E', 'L', 'L', 'O', 0x00 Item1: .byte 'B', 'O', 'N', 'J', 'O', 'U', 'R', 0x00 Item2: .byte 'C', 'I', 'A', 'O', 0x00 .org 0x00FA .word Init .word Init .word Init
实现方案
采纳@NickWestgate提出的拆分表设计思路,以及@Michael提出的将初始指针计算逻辑外提的优化建议,我将原有如下结构的代码:
PROCESS_MUSIC: ; ... BNE MusDoB MusChanA: ; ... LDA MUSICA,X BNE MusCmdToneA ; ... JMP MusChanA MusCmdToneA: ; ... BNE MusNoteA ; ... MusNoteA: ; ... LDA MUSICA,X ; ... MusDoB: ; ... BNE MusDoDone MusChanB: ; ... LDA MUSICB,X BNE MusCmdToneB ; ... JMP MusChanB MusCmdToneB: ; ... BNE MusNoteB ; ... MusNoteB: ; ... MusDoDone: RTS
重构为了更通用的子程序:
PROCESS_MUSIC: LDX #0x01 PerChannel: ; ... BNE EndPerChannel LDA MusicTableL,X STA tmp0 LDA MusicTableH,X STA tmp1 MusChan: ; ... LDA (tmp0),Y BNE MusCmdTone ; ... BEQ MusChan MusCmdTone: ; ... BNE MusNote ; ... MusNote: ; ... LDA (tmp0),Y ; ... EndPerChannel: DEX BPL PerChannel RTS
同时新增了如下数据表:
MusicTableL: .byte <MUSICA .byte <MUSICB MusicTableH: .byte >MUSICA .byte >MUSICB
该方案不再需要我最初编写的LoadFromTable函数,整体代码结构更加简洁清晰。
内容的提问来源于stack exchange,提问作者msbit
相关产品推荐
相关产品推荐

