【问题标题】:Why does sp point to start of RAM on 6502 assembler?为什么 sp 指向 6502 汇编器上 RAM 的开始?
【发布时间】:2021-08-30 04:25:05
【问题描述】:

我正在使用 ca65 汇编器 (https://cc65.github.io/doc/ca65) 来运行我的项目。 我知道 6502 的 SP 寄存器指向堆栈位置的低字节($01SP)。

但我不知道 (sp) 在代码中实际上是如何工作的。

在 ca65 的运行时,它具有将 A 压入堆栈的函数:

pusha:  ldy     sp              ;
        beq     @L1             ;
        dec     sp              ; 
        ldy     #0              ;
        sta     (sp),y          ;
        rts                     ;

但是为什么它不将值压入堆栈呢?为什么它会将值从 0 保存到内存中?

例如,如果我执行此代码:

ldx #$ff
txs
lda #$cc
jsr pusha

我希望在堆栈的内存位置看到$cc,但它把$cc 保存到堆栈下的内存中。

我从模拟器日志中得到的结果,其中 A、X、Y、SP - 寄存器,OP - 当前操作码,PC - 程序计数器,SPData - 堆栈数据和 MemData,它是 RAM:

;Load stack pointer into X    
LDX 8001, A=0, X=0, Y=0, SP=0, addr=ff, op=a2, PC=8002, SPData=0,0,0,0,0,0,0,0,0, MemData=0,0,0,0,0,0,0,0,0
;Save stack pointer from X to SP
TXS 0, A=0, X=ff, Y=0, SP=0, addr=0, op=9a, PC=8003, SPData=0,0,0,0,0,0,0,0,0, MemData=0,0,0,0,0,0,0,0,0
;Load $CC into A
LDA 8004, A=0, X=ff, Y=0, SP=ff, addr=cc, op=a9, PC=8005, SPData=0,0,0,0,0,0,0,0,0, MemData=0,0,0,0,0,0,0,0,0
;Jump to ca65's runtime func "pusha" to save A into stack
JSR 810c, A=cc, X=ff, Y=0, SP=ff, addr=a4, op=20, PC=8008, SPData=0,0,0,0,0,0,0,0,0, MemData=0,0,0,0,0,0,0,0,0
LDY 0, A=cc, X=ff, Y=0, SP=fd, addr=0, op=a4, PC=810e, SPData=0,7,80,0,0,0,0,0,0, MemData=0,0,0,0,0,0,0,0,0
BEQ 8117, A=cc, X=ff, Y=0, SP=fd, addr=c6, op=f0, PC=8110, SPData=0,7,80,0,0,0,0,0,0, MemData=0,0,0,0,0,0,0,0,0
DEC 1, A=cc, X=ff, Y=0, SP=fd, addr=0, op=c6, PC=8119, SPData=0,7,80,0,0,0,0,0,0, MemData=0,0,0,0,0,0,0,0,0
DEC 0, A=cc, X=ff, Y=0, SP=fd, addr=0, op=c6, PC=811b, SPData=0,7,80,0,0,0,0,0,0, MemData=0,ff,0,0,0,0,0,0,0
STA 0, A=cc, X=ff, Y=0, SP=fd, addr=ff, op=91, PC=811d, SPData=0,7,80,0,0,0,0,0,0, MemData=ff,ff,0,0,0,0,0,0,0
;here I want to see $cc into SPData, but it was pushed into MemData
RTS 0, A=cc, X=ff, Y=0, SP=fd, addr=cc, op=60, PC=811e, SPData=0,7,80,0,0,0,0,0,0, MemData=cc,ff,0,0,0,0,0,0,0

要构建的控制台命令是:

    ca65 --cpu 6502 -I ${HOME}/cc65/asminc -U arch/boot.s -o arch/boot.o

【问题讨论】:

  • 显然运行时已经设置了一个单独的堆栈。你在源码中看到的sp不是cpu的SP寄存器。它是零页中的 16 位变量。
  • 所以,他们有不同的意义,非常感谢!
  • 在 6502 中,您无法直接访问 sp(您可以执行 txs 或 tsx)要将值压入堆栈,您使用 pha 并拉取 pla。
  • 如果它对上下文有帮助,C 语言通常被实现为需要访问一堆相对于当前堆栈指针的值。所以堆栈顶部有一大块内存,它随机访问。 6502 不提供对堆栈的那种访问。再加上 C 标准下硬件堆栈非常小,这意味着 6502 的 C 编译器倾向于实现软件堆栈。此外,CPU 寄存器通常只称为 S,而不是 SP,如果有帮助的话。

标签: assembly computer-science 6502


【解决方案1】:

您是对的,6502 在内存位置 $0100 到 $01ff 中有一个硬件堆栈。 6502中有一个栈指针,一个字节宽,叫做S

但 ca65 运行时也使用单独的堆栈,以不同的方式实现。它有一个名为sp 的零页变量,它指向不同的区域。这个区域是pusha 存储A 的地方。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2014-04-25
    • 2019-08-02
    相关资源
    最近更新 更多