为什么这段NES 6502汇编代码在移动到一个有作用域的过程中不起作用?

huangapple go评论75阅读模式
英文:

Why this NES 6502 assembly code doesn´t work when moved to a scoped proc?

问题

I have a snippet that clears memory before initializing a game in NES 6502 assembly. When I leave the code inside the reset proc like so, it works:

.proc reset
  SEI
  CLD

  LDX #0
  ClearRAM:
    STA $000,x
    STA $100,x
    STA $200,x
    STA $300,x
    STA $400,x
    STA $500,x
    STA $600,x
    STA $700,x
    INX
    BNE ClearRAM
.endproc

However, if I try to move this ClearRAM snippet inside a scoped proc:

.scope Memory
  .proc clear
    LDX #0
    ClearRAM:
      STA $000,x
      STA $100,x
      STA $200,x
      STA $300,x
      STA $400,x
      STA $500,x
      STA $600,x
      STA $700,x
      INX
      BNE ClearRAM
    RTS
  .endproc
.endscope

And then load it like so:

.proc reset
  SEI
  CLD

  JSR Memory::clear
.endproc

It stops working. It's like it loops forever in the ClearRAM loop.

Any idea what I am doing wrong?

Thank you!

英文:

I have a snippet that clears memory before initializing a game in NES 6502 assembly. When I leave the code inside the reset proc like so, it works:

.proc reset
  SEI
  CLD

  LDX #0
  ClearRAM:
    STA $000,x
    STA $100,x
    STA $200,x
    STA $300,x
    STA $400,x
    STA $500,x
    STA $600,x
    STA $700,x
    INX
    BNE ClearRAM
.endproc

However, if I try to move this ClearRAM snippet inside a scoped proc:

.scope Memory
  .proc clear
    LDX #0
    ClearRAM:
      STA $000,x
      STA $100,x
      STA $200,x
      STA $300,x
      STA $400,x
      STA $500,x
      STA $600,x
      STA $700,x
      INX
      BNE ClearRAM
    RTS
  .endproc
.endscope

And then load it like so:

.proc reset
  SEI
  CLD

  JSR Memory::clear
.endproc

It stops working. It's like it loops forever in the ClearRAM loop.

Any idea what I am doing wrong?

Thank you!

答案1

得分: 6

你的代码清除了前2K的RAM内存。(我不知道NES是否有超过2K的内存。)

因为栈总是位于使用6502 CPU的系统中的前1K内存中(更精确地说:在100h...1FFh范围内),所以你的程序还清除了栈。

JSR 保存了程序流在 RTS 后继续执行的地址到栈中,而 RTS 指令则从栈中读取该地址。

如果你擦除了栈的内容,RTS 将从栈中读取一些错误的值,并跳转到那个地址。

如果你的程序中的 A 寄存器包含值 12h,那么 RTS 指令将从栈中读取 1212h,程序将在地址 1212h(在 JSR 后的 RTS 指令后)而不是在 JSR 后的下一条指令处继续执行。

英文:

Your code clears the first 2K of RAM memory. (I don't know if the NES has more than 2K of memory.)

Because the stack is always located in the first 1K of memory on systems using a 6502 CPU (to be more precise: in the range 100h...1FFh), your program also clears the stack.

The JSR saves the address where the program flow shall continue after the RTS to the stack and the RTS instruction reads that address from the stack.

If you erase the content of the stack, RTS will read some bad value from the stack and jump to that address.

If the A register in your program contained the value 12h, the RTS instruction will read 1212h from the stack and program execution will continue at address 1212h (after the RTS instruction) instead of the instruction following the JSR.

huangapple
  • 本文由 发表于 2023年8月4日 23:31:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76837338.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定