//循环程序设计


例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,那么显然是错误的