0

我有这个代码:

        jsr cls
        ldx #$00    ;loads 0 into x
        stx tmp     ; stores x in tmp
        ldx #<scr1
        ldy #>scr1
printToScreen
        stx zpb+0
        sty zpb+1
        lda (zpb),y
        ldx tmp.       ; loads x from tmp
        beq done
        sta screen_start,x
        inx
        stx tmp        ; stores new x in tmp
        bne printToScreen
done
        rts

tmp = $C8
zpb = $fb
scr1 byte 'some text'
byte 0

我想创建将字符串打印到屏幕的例程。参数是字符串的地址和用作计数器的 X 寄存器。由于 X 也在函数内部使用,因此我将其值存储在 tmp 变量中。

但是这段代码什么也没打印。我对组装完全陌生,所以可能我不明白这应该如何工作。请参阅代码注释。我在这里做错了什么?

4

2 回答 2

1
            jsr cls
            ldy #$10    ; loads $10 into x as a string length
            lda #<scr1
            sta zpb+0
            lda #>scr1
            sta zpb+1
printToScreen
            lda (zpb),y
            sta screen_start,y
            dey
            bne printToScreen
            rts

我会那样做。老实说,我没有测试我上面写的代码。我已经按照我认为应该做的方式改变了它。

关于您的代码:不需要在每次循环迭代中覆盖 zpb 和 zpb+1 。您在执行“lda (zpb),y”之前忘记设置 Y 索引寄存器 - 可能它应该为零。在“ldx tmp”之后,您不会将其与任何内容进行比较(应该是 cpx #something),因此默认情况下您将其与零进行比较(beq done)并且 cpu 退出程序,因为 X==0。所以你的程序在内存的某个地方写了一个字节然后就退出了。

于 2021-09-30T09:43:41.600 回答
1

.X 应该是正在打印的字符串的长度吗?

您当前的代码:

printToScreen
    stx zpb+0
    sty zpb+1
    lda (zpb),y
    ldx tmp.
    beq done
    sta screen_start,x
    inx
    stx tmp
    bne printToScreen

认为您正在尝试做的是:

  1. 在 .X 和 .Y 中传递字符串的地址
  2. 将其存储在zpb
  3. 在 zpb 使用间接寻址获取字节并将它们存储到屏幕screen_start

几个问题:

  • lda (zpb),y是正确的寻址模式,但您永远不会初始化 .Y 寄存器。因此,第一次调用时的 .Y 寄存器实际上是使用您传递的地址的最高有效字节开始
  • inx stx tmp bne printToScreen..的组合当你这样做时inxbne你说的是“增加 .X,保存它,如果它不等于零,则分支到printToScreen”。但这实际上看起来像是您正在尝试复制 256 个字节。
  • 尽管从未初始化 .Y,但您也永远不会更改它,因此它将有效地始终获得由 .Y (间接)指向的相同字节zpb
  • 您正在使用 #$00 初始化 .X 并将其存储在 中tmp,但这确实不需要按照我认为您正在尝试做的事情来完成。
  • 如果 .X 应该是长度,那么您实际上并没有在任何地方定义它……您实际上是在为 256 个字节执行此操作(除非那是您想要的?)
  • 您一直将 .X 和 .Y 存储在 .X 和 .Y 中zpb,但这使您无法实际使用 .X 和 .Y

也就是说,我认为可能对您有用的是:

    jsr cls     ; assuming this is a routine to clear the screen
    ldx #<scr1
    ldy #>scr1
    stx zpb+0
    sty zpb+1
    ldy #$00
printToScreen
    lda (zpb),y
    beq done
    sta screen_start,y
    iny
    bne printToScreen
done
    rts
scr1 .asc 'some text'
    .byt 0

这将做的是:

  • 将位置存储scr1zpb
  • 循环scr1并将其存储在screen_start,并在以下情况下结束:
    • 当前字节是 0 字节(在进行实际复制之前它会检查它);或者
    • .Y 变为零(同样,在初始化之后)
于 2021-10-03T19:09:55.283 回答