2011-05-16 75 views
9

我想用6502处理器在程序集中编写一个while循环,我无法弄清楚如何编写十六进制代码。我见过使用速记写的例子,其中有一个标签,用于循环开始和结束的位置,但我没有看到任何实际的十六进制代码。在程序集中编写一个while循环

两个码我看是有用的是:

  1. 在存储器比较一字节到X章(简写:CPX,己烷:EC)。如果相等,
  2. 这个设置Z标志为零,如果
  3. 分公司X字节Z标志= 0(简写:BNE,十六进制:D0)
+5

为什么要使用十六进制代码而不是使用汇编程序? – 2011-05-16 17:19:58

+0

@jnhyf“十六进制代码”?你正在使用哪种IDE,汇编器或编译器?你有什么经验与6502组装? – bzlm 2011-05-16 17:20:48

+2

我希望你没有告诉我们你正在编写一个6502程序而不使用汇编程序。你用什么开发系统?苹果 ][ ?或者是什么? – 2011-05-16 17:22:00

回答

6

这里有一个地方让你开始:http://www.obelisk.demon.co.uk/6502/。该页面提供了一个可以在PC上运行的交叉汇编器。那可能对你来说是一个很好的开发平台。

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

- 准备“源文件”,所谓, 象征性的指令,你 叫“速记”
- 使用 汇编,翻译该源 文件到机器指令 6502了解
- 加载 翻译成6502
- 告诉 6502执行翻译 机器指令

你举的例子程序试图LEN内存字节复制从SRCDST

你格式化是这样的:

 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执行机器代码所包含的操作。

+0

谢谢,这帮助,但我仍然对如何像从该网站这个例子清楚:“ \t LDX#0 \t \t;启动第一个字节 _LOOP \t LDA SRC,X \t;将其 \t STA DST,X \t INX \t \t;然后撞击指数... \t CPX #LEN \t; ......直到我们到达了极限 \t BNE _LOOP“ 可以用十六进制来表示。 _loop标签在速记中很重要,但在实际的机器代码中我没有看到如何获得类似的内容。 对不起,我不知道如何格式化代码。 – jnhyf 2011-05-16 17:59:42

+0

@jnhyf您*真的*需要将您的问题分为“我如何在6502机器码中编写此代码”和“我如何将该代码转换为十六进制符号”。就目前而言,很难帮助你。 – bzlm 2011-05-17 12:51:24

+0

@jnhyf - 有两个步骤:(1)用汇编语言编写程序,你称之为“速记”(一个我从未听过的术语,顺便说一句); (2)将该汇编语言文件提供给汇编程序,然后汇编出您想要的十六进制代码。 – 2011-05-17 19:25:29

1

一个while声明的真正含义:

  1. 测试条件
  2. 如果条件为假,去5
  3. 做点什么
  4. 回去1(一个简单的JMP或分支)
  5. 程序的其余部分

With 6502,除非你能做出很多假设,否则这些都不会很简单。如果你正在测试的条件总是要成为一个寄存器,比较指令(cmp,cpx,cpy)和分支指令显然是你所需要的1.

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

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

处理漂浮物?如果你已经编写了一个浮点程序包(例如Commodore 64 ROM BASIC浮点程序),那么你需要使用它们。

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

所以真的,这取决于你正在处理的数据类型,但在6502中的任何实现while应该几乎遵循上述。

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

2

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

实例:
$D0 $00:无操作:分支进到下一指令不管条件如何
$D0 $FE:分支点回到自身,创建一个无限循环如果Z=0

+0

Upvote解码和回答措辞严厉的问题。 ; - ) – 2015-02-20 08:58:39

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被赋值$1234loop将被分配的指令的地址之后。所以在这种情况下,由于LDX #len占用2个字节(如我将很快显示的),因此loop设置为$4000 + 2 = $4002。这是由汇编程序自动完成的,但当然你也可以在纸上做所有这些。

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

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

我怎么知道这个?那么,我刚把上面的程序粘贴到网上的6502汇编程序中,网址为http://www.masswerk.at/6502/assembler.html。它甚至可以显示你组装和机器代码之间的详细映射:

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!因此,如果你手动完成这项工作,只需要将其他所有内容翻译成机器代码,那么当你跳转时,计算下一个指令起始地址和跳转目标地址之间的差异。对于向后跳跃应该是负面的,对于向前跳跃应该是正面的。

+0

Upvote获得最佳循环。 ; - ) – 2015-02-20 08:59:15