//循环程序设计
例1://找最大值 从地址2100-地址21FF中找最大值,结果送地址2200
2000:LDX #$00 //初始化计数器X的内容=00
2002:LDA #$00 //先假设最大值=00,这是最小的可能值
2004:CMP $2100,X //下一个数比当前最大值大吗?
2007:BCS $200C //否,维持寄存器A的值不变
2009:LDA $2100,X //是,用该数代替最大值
200C:INX //计数器X的内容加1
200D:BNE $2004 //继续循环比较,直到全部比较完毕
200F:STA $2200 //结果送地址2200
2012:RTS
通过上面的程序,我们可以知道,一个循环程序一般是由4个部分组成
①初始化部分. 它建立计数器的初值和其他变量的起始值
2000:LDX #$00 //初始化计数器X的内容=00
2002:LDA #$00 //先假设最大值=00,这是最小的可能值
②处理部分. 在这部分进行实际的数据处理,这是循环程序中要求重复执行的那段代码
2004:CMP $2100,X //下一个数比当前最大值大吗?
2007:BCS $200C //否,维持寄存器A的值不变
2009:LDA $2100,X //是,用该数代替最大值
③循环控制部分. 它为下一轮循环做好修正计数器的准备,并且判断是否循环结束
200C:INX //计数器X的内容加1
200D:BNE $2004 //继续循环比较,直到全部比较完毕
④结束部分. 它分析和存放结果
例2://数据块搬家 地址2100-21FF的内容送地址2200-22FF
2000:LDX #$00 //初始化部分
2002:LDA $2100,X //处理部分
2005:STA $2200,X
2008:INX //循环控制部分
2009:BNE $2002
200B:RTS //结束部分
例3. 在文曲星的程序中,大量使用了下面的这种循环方式,请看
2000: LDX #$9C
2002: LDA $3FFF,X
2005: STA $1FFF,X
2008: DEX
2009: BNE $2002
200B: RTS
这段程序实现的是将地址 4000-409B 的内容送地址 2000-209B
发送的字节数是 9C个
初学者可能会说,为什么是 LDA $3FFF,X STA $1FFF,X 呢,为什么不是 LDA $4000,X STA $2000,X 呢?
这里 3FFF + 9C = 309B,因为最后的地址是309B,如果是 LDA $4000,X,那么最后的地址岂不是 4000 + 9C = 409C吗?
显然是错误的.所以地址要减 1
例4:在我们前面所讲的数据传送例子中,只能实现少量数据的传送,这里我们讲讲如何实现大量数据的传送
//大量数据的搬家 地址2000-2FFF的内容送地址3000-3FFF
2000:LDY #$00
2002:LDA #$00
2004:STA $40
2006:LDA #$20
2008:STA $41
200A:LDA #$00
200C:STA $42
200E:LDA #$30
2010:STA $43
2012:LDA ($40),Y
2014:STA ($42),Y
2016:LDA $40
2018:CMP #$FF
201A:BNE $2023
201C:LDA $41
201E:CMP #$2F
2020:BNE $2023
2022:RTS
2023:INC $40
2025:BNE $2029
2027:INC $41
2029:INC $42
202B:BNE $202F
202D:INC $43
202F:JMP $2012
这个程序的代码稍微长了些,但是我们分析一下,发现并不复杂
首先要说明一下,在这个程序中我们使用了 后变址Y间址 的寻址方式
地址40 41 放源地址
地址42 43 放目标地址
开始的时候,对地址40,41,42,43进行初始化为 40:00 20 00 30,并且让寄存器Y的值=00
该段代码如下:
2000:LDY #$00
2002:LDA #$00
2004:STA $40
2006:LDA #$20
2008:STA $41
200A:LDA #$00
200C:STA $42
200E:LDA #$30
2010:STA $43
然后运用 后变址Y间址 的寻址方式,先读取地址40 41的值,把地址40的值作为源地址的低8位,地址41的值为高8位
这里一开始(40)=00,(41)=20,那么就是将地址[2000+Y]的内容送寄存器A,由于一开始就让寄存器Y的值=00
所以执行该指令的结果就是将地址2000的值送寄存器A
然后 同样用 后变址Y间址 的寻址方式 先读取地址42 43的值,把地址42的值作为目标地址的低8位,地址43的值为高8位
这里一开始(42)=00,(43)=30,那么就是将寄存器A的值送地址[3000+Y],即将A的值送地址3000
该段代码如下:
2012:LDA ($40),Y
2014:STA ($42),Y
然后就是判断地址40,41的内容是不是(40)=FF,(41)=2F,如果相等,说明数据已经传送完成.
如果不相等,那么把地址40,42的值加1,继续传送.这里有段代码可能有人不明白
2023:INC $40
2025:BNE $2029
2027:INC $41
2029:INC $42
202B:BNE $202F
202D:INC $43
如果地址40的值加1后,地址40的值=00,那么地址41的值就应该加1,比如开始(40)=FF,(41)=20
地址40的值加1后,(40)=00,如果此时地址41的值不加1,那么(40)=00,(41)=20,那么显然是错误的