//addr :代表8位地址 addr16:代表16位地址 data :立即数
[转移指令]
程序在大多数的情况下是按顺序执行的,即依靠程序计数器PC不断自动加1的操作,指示出下一条指令所在地址,这样
计算机就可以按照程序中指令的排列顺序一条接一条的执行下去.
不过在某些条件下,需要改变程序顺序执行的次序,而转入执行另一个地址中存放的指令,这就要依靠转移指令来实现
在6502中有无条件转移和条件转移,无条件转移是无条件的将程序转向另外一个地址,而条件转移是当满足某些条件时
程序才发生转移,比如C=0,C=1,Z=1,Z=0等条件.
无条件转移的跳转步长为整个64K内存,即可以跳转到任意地址
条件跳转指令的跳转步长是有限制的 正跳转127个字节 负跳转128个字节
1. JMP--无条件转移指令
符号码格式 | 指令操作码 | 寻址方式 |
JMP $data16 | 4C | 绝对寻址 |
JMP ($data16) | 5C | 间接寻址 |
2. 条件转移指令
符号码格式 | 指令操作码 | 寻址方式 | 指令功能 |
BEQ $data16 | F0 | 相对寻址 | 如果标志位Z=1则转移,否则继续 |
BNE $data16 | D0 | 相对寻址 | 如果标志位Z=0则转移,否则继续 |
BCS $data16 | B0 | 相对寻址 | 如果标志位C=1则转移,否则继续 |
BCC $data16 | 90 | 相对寻址 | 如果标志位C=0则转移,否则继续 |
BMI $data16 | 30 | 相对寻址 | 如果标志位N=1则转移,否则继续 |
BPL $data16 | 10 | 相对寻址 | 如果标志位N=0则转移,否则继续 |
BVS $data16 | 70 | 相对寻址 | 如果标志位V=1则转移,否则继续 |
BVC $data16 | 50 | 相对寻址 | 如果标志位V=0则转移,否则继续 |
这里我重点讲讲用的最多的 BEQ,BNE,BCC,BCS
①BNE 如果标志位 Z = 0则转移,否则继续
在6502中,要判断两个数是不是相同,就可以使用该指令
例1: 判断 地址3000与地址3001的内容是不是相同,若相同,则送 01 到地址3002,否则送 00
A 2000
2000:LDA $3000 ;读取地址3000的内容到寄存器A
2003:CMP $3001 ;和地址3001的内容比较,其实就是把地址3000的内容减去地址3001的内容
2006:BNE $200E ;若Z = 0,说明结果不等于 0 ,那么说明两个地址的内容不同,程序转到地址200E
2008:LDA #$01 ;这里说明Z = 1,那么说明两个数相同
200A:STA $3002
200D:RTS
200E:LDA #$00
2020:STA $3002
2023:RTS
从上面的程序,我们知道,要比较两个数是不是相同,需要先使用比较指令,然后通过标志寄存器的状态位来判断是不是相同
②BEQ 如果标志位 Z = 1,那么就转移,否则继续
例: 判断 地址3000与地址3001的内容是不是相同,若相同,则送 01 到地址3002,否则送 00
A 2000
2000:LDA $3000
2003:CMP $3001
2006:BEQ $200E
2008:LDA #$00
200A:STA $3002
200D:RTS
200E:LDA #$01
2020:STA $3002
2023:RTS
该程序和上面的几乎是一样的,大家分析一下吧.
③BCC 如果标志为 C = 0,转移,否则继续
该指令可以用来判断两个数谁大谁小
例:判断地址3000和地址3001的内容,谁大谁小,若地址3000的内容大,送 01 到地址3002,若地址3001的内容大,送 02到地址3002
如果都是一样大,送00到地址3002
A 2000
2000:LDA $3000 ;读取地址3000的内容到寄存器A
2003:CMP $3001 ;和地址3001的内容比较,其实就是把地址3000的内容减去地址3001的内容
2006:BEQ $2010 ;如果 Z = 1,那么说明相同,转地址2010,送 00 到地址3002
2008:BCC $2016 ;如果 C = 0,那么说明地址 3000的内容 < 地址3001的内容,转地址2016,送 02到地址3002
200A:LDA #$01 ;这里说明 C = 1,那么说明地址3000的内容 > 地址3001的内容
200C:STA $3002
200F:RTS
2010:LDA #$00
2012:STA $3002
2015:RTS
2016:LDA #$02
2018:STA $3002
201B:RTS
④BCS 若 C = 1,则转移,否则继续
和上面的用法是一样的,大家用该指令完成上面的功能吧!
3. 转移到子程序指令JSR和从主程序返回指令RTS
JSR指令仅仅是 绝对寻址,它的操作码是 20
RTS指令是 隐含寻址,它的操作码是 60
在程序设计中,如果程序比较大,那么一般是采取模块化设计方法,把一个大的程序分割成若干小程序,然后在主程序调用这些小程序
在6502中就是用JSR这条指令调用子程序的.
转子指令和转移指令的区别在于转移指令控制程序转出后就不再返回了,而转子指令使程序转向子程序后,当子程序被执行完后还要返回
主程序被打断处,实现这个返回是依靠在子程序末尾使用一条子程序返回指令RTS,就可以控制程序自动返回到主程序被打断处
例如: 指令
.
.
.
2000:JSR 2100 //程序执行到这里时,就跳转到地址2100开始执行那里的程序
2003:.
.
.
2100:指令
.
.
.
RTS //当程序执行到这里后,会自动返回主程序被打断处,即跳转到地址2003那里继续执行