1.3.3 6502指令集
6502指令集中的每条指令都有一个由三个字符组成的助记符。在汇编语言源文件中,每行代码包含一条指令助记符,后面跟着该指令的操作数。助记符和操作数的组合定义了寻址模式。6502支持多种寻址模式,为访问寄存器和内存中的数据提供了极大的灵活性。在这里将只使用立即数寻址模式,在该模式中,操作数本身就是一个数值,而不是指向包含数值的寄存器或内存位置。立即数前面有一个#字符。
在6502汇编中,十进制数字没有前缀,而十六进制数字前面有一个$字符。例如,立即数#48是十进制数字,而#$30是十六进制数字。
下面将用一些汇编代码示例来展示6502的算术功能。下面的示例中使用了5条6502指令:
·LDA向寄存器A加载一个数值。
·ADC将进位标志(C标志)作为加法运算的额外输入和输出,即带进位的加法。
·SBC将进位标志作为减法运算的额外输入和输出。
·SEC将进位标志直接设为1。
·CLC将进位标志直接清零。
由于进位标志是加法和减法指令的输入,因此在执行ADC或SBC指令之前要确保该值是正确的。在启动加法操作之前,C标志必须清零,以指示没有来自先前加法的进位。执行多字节加法(例如,使用16位、32位或64位数字)时,在进行高位字节的加法运算时,需要将相邻的低字节加法运算产生的进位作为输入参与运算。如果在ADC指令执行时C标志为1,则效果是将结果加1。ADC执行完成后,C标志用作结果的第9位:C标志结果为0表示没有进位,结果为1表示有来自8位寄存器的进位。
对于使用6502汇编语言的新手程序员来说,使用SBC指令执行减法运算往往会更感到困惑。小学生在学习减法时,如果要从一个较小的数中减去一个较大的数,则需要使用借位技术。在6502中,C标志代表借位的反逻辑。如果C为1,则借位为0;如果C为0,则借位为1。因此,在没有借位的情况下执行减法时,需要在执行SBC命令之前将C标志设为1。
表1.4中的示例使用6502作为计算器,使用代码中直接定义的输入,并将结果存储在A寄存器中。“结果”那一列显示A寄存器以及N、V、Z和C标志的最终值。
表1.4 6502算术指令序列
如果读者手边没有一台具有汇编器和调试器的6502计算机,则可以在Web浏览器中在线运行免费的6502模拟器。访问https://skilldrick.github.io/easy6502/可以得到一个优秀的模拟器,访问该网站并向下滚动,直到找到带有用于汇编和运行6502代码按钮的默认代码清单。用表1.4中的一组三条指令替换默认代码清单,然后对代码进行汇编。如果要检查序列中每条指令的效果,可以使用调试器控制指令单步执行,并观察处理器寄存器的结果。
本节非常简要地介绍了6502处理器及其一小部分功能。此处的一个要点是展示执行简单加法时的进位问题和执行减法时的借位问题所面临的挑战。从查尔斯·巴贝奇到6502的设计者,计算机架构师已经开发出了计算问题的解决方案,并使用可用的最好的技术来实现这些解决方案。