字节指令在6502汇编程序中做了什么?

时间:2015-03-02 05:20:30

标签: assembly 6502 nintendo

首先:抱歉,如果这是一个骗局!我搜索了一下,但没有找到一个令人满意地解释这个的资源。

这里有一个问题!

我想了解.byte指令的作用。不同的消息来源说不同的东西,其中的主旨是:

  

.db,DB,.byte等将您指定的确切字节列为数据而不是指令   (http://forum.6502.org/viewtopic.php?f=2&t=2374

cc65手册同样含糊不清:

  

.byte:定义字节大小的数据。必须遵循一系列   (字节范围)表达式或字符串。

     

示例:

        .byte   "Hello "
        .byt    "world", $0D, $00
     

http://www.cc65.org/doc/ca65-11.html

我不知道这意味着什么。我认为与定义数据相关的所有操作都是读写内存地址的变化。所以这样的事情(来自NES开发的tut)

; Number of PRG-ROM blocks
.byte $01
; Number of CHR-ROM blocks
.byte $01
; ROM control bytes: Horizontal mirroring, no SRAM
; or trainer, Mapper #0
.byte $00, $00

它到底做了什么?这一切都可以用操作码来解释,还是做得更漂亮?对我来说,它似乎可能是从零页面开始编写顺序数据,类似这样的东西??:

LDA #$01
STA $00
LDA #$01
STA $01
LDA #$00
STA $02
LDA #$00
STA $03

我离开这里了吗?我一直在阅读6502 Software Design by Leo Scanlon并且我没有看到任何对该(或任何)指令的引用。我正在学习6502用于NES开发的目的,所有示例代码都充满了.byte.ascii和其他几个指令。在尝试浏览用户贡献的NES教程的世界之前,我真的想尝试从像Scanlon一书这样的学术文本中获得6502的坚实基础,但这已经成为我理解NES 6502的障碍。

2 个答案:

答案 0 :(得分:3)

这里有两个不同的事情需要考虑。您正在混合ROM内存位置,其中值始终在这里(它们不能,也不应该被“加载”)和RAM,其中内容在系统启动时未定义,以及任何位置你想要使用的数据必须在某个时候被有效地“加载”。

例如:

.byte $00, $01, $02, $03

将在ROM中的某处添加4个字节。它们不是“加载”的,它们总是在这里。

相反:

ldx #$00
stx somewhere
inx
stx somewhere+1
inx
stx somewhere+2
inx
stx somewhere+3

如果某处指向RAM,那么这将在此位置加载字节$ 00,$ 01,$ 02,$ 03。加载这些值后,这些字节只在RAM位置,直到用其他值覆盖RAM。

现在,就你的例子而言,这实际上是一个令人困惑的例子,因为它定义了iNES头格式的字节,总长度为16个字节。 这些字节既不是ROM也不是RAM的一部分,而只是用于在PC上存储NES ROM的标头惯例。

你看到的例子只是欺骗汇编程序,认为标题是ROM的一部分,实际上它不是。这只是其中一种方法。另一种方法是使用汇编程序生成一个干净的“原始”ROM映像,并在构建时单独添加iNES头,这就是我个人的做法。

我希望这会有所帮助。

答案 1 :(得分:1)

在阅读评论后,我试着给出答案:

在大多数计算机的内存中,所有类型的数据(包括代码)都以字节的形式存储。

这意味着汇编程序必须最后将所有指令转换为字节。

指令“LDA $ 1234”将存储为三个字节:$ AD,$ 12和$ 34。

使用“.byte”,“。word”和“。long”指令(可能6502不支持“.long”)你可以直接指示汇编程序将一些给定的字节放到某个内存位置而不是表示某条指令的字节。

想象一下作为操作系统一部分的以下代码:

LDX $2000
STA 0,X
...
JSR $2001

在这种情况下,地址$ 2000的字节将在零页中包含一个地址,其中A寄存器将被写入,而地址$ 2001的字节是实际代码的第一个字节。

从地址$ 2000开始的数据的汇编代码现在可能如下所示:

# Zero-page address where the OS will store the A register
.byte $12
# Actual code called by the OS
LDA $12
...
RTS

我希望这会有所帮助。

---编辑---

关于你的'.ascii“iNES”'行的例子:

这些行仅存在于NES仿真器的程序中,而不存在于真实NES设备的程序中。

当使用非常宽泛的术语“操作系统”时,您可能会说NES仿真器是某种“操作系统”。在这种情况下,示例中“.byte”行的原因与上述相同:

“操作系统”(= NES仿真器)将读取文件的前16个字节,检查这些字节,对这些字节执行某些操作然后实际运行代码。

您可能还在代码中看到了以下几行:

.advance $FFFA
.word vblank, reset, irq

这两行也不是6502汇编程序指令,但它们是汇编程序的指令:

他们指示汇编程序写入六个特殊字节来解决$ FFFA。这是必要的,因为6502 CPU需要六个字节代表地址$ FFFA- $ FFFF的三个特殊地址。