You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C64汇编中如何向子程序传递内存地址参数?

方案1:零页指针传递(最优通用方案)

6502架构下最常用的双字节地址传递方式是使用零页双字节变量做参数,配合(ind),Y间接寻址实现,完全不需要依赖X寄存器做索引,也能兼容KERNAL调用场景:

传参实现

首先你的param要定义在零页区域(C64的$0000~$00FF区域,访问速度最快),调用子程序前写入字符串的高低字节地址:

; 调用示例:传递scr1地址
lda #<scr1      ; 取scr1地址的低字节
sta param
lda #>scr1      ; 取scr1地址的高字节
sta param+1
jsr print_str   ; 调用打印函数

可复用打印函数实现

函数入口先保存所有用到的寄存器,出口恢复,完全不影响外部寄存器状态,也不怕内部调用KERNAL例程修改寄存器:

print_str
    pha         ; 备份A寄存器
    txa
    pha         ; 备份X寄存器
    tya
    pha         ; 备份Y寄存器

    ldy #$00
copy_loop
    lda (param),y   ; 间接寻址:读取param存的地址 + Y偏移的内容
    beq print_done
    sta screen_start,y
    iny
    bne copy_loop
print_done
    pla         ; 恢复Y寄存器
    tay
    pla         ; 恢复X寄存器
    tax
    pla         ; 恢复A寄存器
    rts

方案2:内联参数传递(更省调用代码)

如果希望调用代码更简洁,可以把参数直接写在jsr指令后面,函数自动从返回地址位置读取参数并调整返回地址,不需要手动操作零页变量:

调用示例

jsr print_str
word scr1       ; 直接把字符串地址存在jsr指令后面

函数实现

print_str
    pha
    txa
    pha
    tya
    pha

    tsx
    ; 从栈中读取返回地址(jsr执行后压栈的是下一条指令地址,也就是参数的位置)
    lda $0101,x
    sta param
    lda $0102,x
    sta param+1

    ; 读取2字节地址参数存入临时指针
    ldy #0
    lda (param),y
    sta tmp_ptr
    iny
    lda (param),y
    sta tmp_ptr+1

    ; 调整返回地址,跳过2字节参数,避免返回后执行参数内容
    clc
    lda param
    adc #2
    sta $0101,x
    lda param+1
    adc #0
    sta $0102,x

    ; 打印逻辑和方案1一致
    ldy #0
copy_loop
    lda (tmp_ptr),y
    beq done
    sta screen_start,y
    iny
    bne copy_loop
done
    pla
    tay
    pla
    tax
    pla
    rts

常见问题解答
  • 关于代码重复:6502汇编开发中完全不接受这种同质化代码重复,C64可用内存仅64KB,重复逻辑会快速占用宝贵的存储空间。可复用函数实现难度很低,只要掌握寄存器压栈恢复、零页指针两个核心技巧就能实现绝大多数通用函数。
  • 关于寄存器占用:6502的栈有256字节空间,函数入口备份寄存器、出口恢复的开销极小,只要不是极端深度的嵌套调用完全够用,不需要担心寄存器冲突问题。

内容的提问来源于stack exchange,提问作者user2297996

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:54:01