在汇编中编写while循环

时间:2011-05-16 17:14:13

标签: loops assembly while-loop hex 6502

我正在尝试使用6502处理器在汇编中编写while循环,我无法弄清楚如何编写十六进制代码。我已经看过使用简写编写的示例,其中有一个标签,表示循环应该从哪里开始和结束但是我没有看到任何实际的十六进制代码。

我认为有用的两个代码是:

  1. 将内存中的字节与X reg(速记:CPX,十六进制:EC)进行比较。如果相等且
  2. ,则将Z标志设置为零
  3. 如果Z标志= 0,则分支X字节(简写:BNE,十六进制:D0)

4 个答案:

答案 0 :(得分:6)

以下是您开始的地方:http://www.obelisk.demon.co.uk/6502/。该页面具有可在PC上运行的交叉汇编程序。 可以成为一个很好的开发平台。

在做任何事情之前,你必须了解6502的操作理论。然后你必须了解软件开发过程,包括:

- 准备一个“源文件”,所谓的,    你的象征性指示    叫“速记”
- 使用    汇编程序,翻译该来源    归档到机器指令中    6502理解
- 加载    翻译成6502
- 告诉    6502执行翻译    机器说明书

您的示例程序尝试将LEN内存字节从SRC复制到DST

你可以这样格式化:

      LDX #0    ; Start with the first byte 
_LOOP LDA SRC,X ; load a byte from SRC into the A register 
      STA DST,X ; store that byte into DST
      INX       ; bump the index register to point to the next SRC and DST locations 
      CPX #LEN  ; have we moved LEN characters?  
      BNE _LOOP ; if not, go move the next one

添加更多语句行后(例如END);在您定义SRCDSTLEN之后,您将整个内容保存在一个名为cploop.txt的文件中。

然后你告诉汇编程序翻译它。汇编程序提供了一个二进制6502机器代码文件,可以表示为您正在讨论的十六进制字节。

您将机器代码文件提供给模拟6502.然后您以某种方式告诉6502执行机器代码所体现的操作。

答案 1 :(得分:3)

这是一个显示程序集(你称之为"简写")和机器代码之间的对应关系的例子。首先,这里是算法的汇编代码,抽象了一些参数:

* = 4000          ; This is the address where our program will be stored

      LDX #len
loop  LDA src,X 
      STA dest,X 
      DEX       
      BNE loop

当然,您无法将其直接转换为机器代码。您还需要填写lensrcdest的值:

src = $1234
dest = $5678
len = 10

关于loop名称的理解是,就像为src分配值$1234一样,loop将被分配后面的指令的地址。因此,在这种情况下,由于LDX #len占用2个字节(我很快会向您显示),因此loop设置为$4000 + 2 = $4002。这是由汇编程序自动完成的,但当然你也可以在纸上完成所有这些。

那么上面的汇编程序的6502机器代码是什么?

A2 0A
BD 34 12
9D 78 56
CA
D0 F7

我怎么知道这个?好吧,我刚刚将上述程序粘贴到http://www.masswerk.at/6502/assembler.html的在线6502汇编程序中。它甚至可以显示程序集和机器代码之间的详细映射:

4000        LDX #LEN        A2 0A
4002 LOOP   LDA SRC,X       BD 34 12
4005        STA DEST,X      9D 78 56
4008        DEX             CA
4009        BNE LOOP        D0 F7
400B

请注意,LOOP的实际值甚至不用于计算BNE LOOP的机器代码,只考虑其相对地址与BNE指令本身的比较:F7是-9,$400B$4002之间的差异是-9!

因此,如果您要手动执行此操作,您只需将其他所有内容转换为机器代码,然后当您进行跳转时,您可以计算下一条指令的起始地址与跳转目的地的地址。对于向后跳跃应该是负的,对于向前跳跃应该是正的。

答案 2 :(得分:2)

分支指令采用单字节有符号相对地址操作数,该操作数被添加到下一条指令的地址以产生分支目标。由于分支指令总是占用2个字节,因此目标地址是分支指令的地址加上(符号扩展)操作数减去2.

示例:
$D0 $00:无操作:无论条件如何,分支都会转到下一条指令 $D0 $FE:分支指向自身,如果Z=0创建无限循环。

答案 3 :(得分:1)

while语句的确意味着:

  1. 测试条件
  2. 如果条件为假,请转到5
  3. 做点什么
  4. 返回1(简单的JMP或分支)
  5. 程序的其余部分
  6. 6502,除非你能做出很多假设,否则这一切都不会非常简单。如果您正在测试的条件总是一个寄存器,则比较指令(cmp,cpx,cpy)和分支指令显然是您需要的。

    如果它将成为存储在内存中的单个字节,那么您需要加载该字节,然后进行比较。

    如果它是以两个字节存储的16位值,则需要加载并测试该字节的每个值。

    处理花车?如果您已经编写或可以使用浮点包(例如Commodore 64 ROM BASIC浮点例程),则需要使用它们。

    您可以看到为什么高级语言具有数据类型。

    实际上,这取决于您正在处理的数据类型,但6502中while的任何实现都应该遵循上述内容。

    如果您知道要比较的数据始终位于X中,并且您的目标始终为+ 127 / -128字节(Bxx指令的范围限制),则您在问题中确定的具体情况是正常的。