//addr  :代表8位地址    addr16:代表16位地址     data  :立即数

[算术运算指令]

1. ADC--累加器,存储器,进位标志C相加,结果送累加器A  A+M+C→A

符号码格式 指令操作码 寻址方式            周期
ADC ($addr,X) 61 先变址X后间址        
ADC $addr 65 零页寻址
ADC #$data 69 立即寻址
ADC $addr16 6D 绝对寻址
ADC ($addr),Y 71 后变址Y间址
ADC $addr,X 75 零页X变址
ADC $addr16,Y 79 绝对Y变址
ADC $addr16,X 7D 绝对X变址

注意:由于进位标志C页会参加运算,所以在做加法运算时,一般要在前面加指令 CLC,清除进位标志

例1:  //两个8位数加法运算演示,目的是将寄存器A的内容加上地址2100的内容,结果送寄存器A

     2000:LDA #$20       //立即数21送寄存器A

     2002:STA $2100      //地址2100的内容为20

     2005:LDA #$21       //寄存器A的内容为21

     2007:CLC            //清除进位标志C,注意:在做加法运算前一定要加该指令

     2008:ADC $2100      //寄存器A的内容和地址2100的内容相加

     200B:RTS

大家可以进入NCTOOLS,输入 A 2000,然后输入上面代码,然后 输入 G 2000,然后按R看寄存器A的值,是不是等于41呢?

 

例2://两个16位数加法运算,这里是将0194+01BA,大家注意看看程序与上面有什么不同.

     在这个程序里,先将要相加的数分别放地址2100,2101,2102,2103,具体是这样的:2100:94 01 BA 01

     然后先将地址2100的内容+地址2102的内容,结果送地址2104

     再将地址2101的内+地址2103的内容,结果送地址2105

     那么地址2104,2105的结果,就是两个16位数相加的结果,这里是034E

 

    2000:LDA #$94        //立即数94送寄存器A

    2002:STA $2100       //寄存器A的内容送地址2100

    2005:LDA #$01        //立即数01送寄存器A

    2007:STA $2101       //寄存器A的内容送地址2101

    200A:LDA #$BA        //立即数BA送寄存器A

    200C:STA $2102       //寄存器A的内容送地址2102

    200F:LDA #$01        //立即数01送寄存器A

    2011:STA $2103       //寄存器A的内容送地址2103

    2014:CLC             //清除进位标志,注意,开始做加法程序前,一定要清除进位标志

    2015:LDA $2100      //地址2100的值送寄存器A

    2018:ADC $2102      //寄存器A的内容 + 地址2102的内容 + C → A,这里C=0

    201B:STA $2104      //寄存器A的内容送地址2104

    201E:LDA $2101      //地址2101的内容送寄存器A

    2021:ADC $2103      //寄存器A的内容 + 地址2103的内容 + C → A,这里C=1,请注意,这里没有用CLC指令

    2024:STA $2105      //寄存器A的内容送地址2105

    2027:RTS            //程序结束

 

    在这个程序里,最重要的就是为什么后面的加法指令前面没有用CLC指令,不是说在做加法前要用CLC指令吗?

但这里就不一样,由于在前面已经用了CLC指令,将C=0,做了一次加法运算后,会影响标志位C

    如果做完第一次加法运算后,C=0,那么说明没有产生进位,C还是等于0,所以没有必要再用CLC指令

    如果做完第一次加法运算后,C=1,那么说明产生了进位,如果再做第二次加法运算前,还使用CLC指令,那么计算的结果

就是错误的,我们来看 第一次运算后,(2104)=4E,如果第二次运算前使用CLC指令,那么01+01+00=02,最后的结果是这样的

(2104)=4E,(2105)=02,那么说明 0194+01BA=024E,我们口算都能知道这个结果是错误的,实际上由于第一次运算后,产生了进位

所以我们要把进位保留即01+01+(C)=01+01+01=03,所以实际的结果是(2104)=4E,(2105)=03

 

2. SBC--从累加器减去存储器和进位标志C,结果送累加器  A-M-C→A

符号码格式 指令操作码 寻址方式
SBC ($addr,X) E1 先变址X后间址
SBC $addr E5 零页寻址
SBC #$data E9 立即寻址
SBC $addr16 ED 绝对寻址
SBC ($addr),Y F1 后变址Y间址
SBC $addr,X F5 零页X变址
SBC $addr16,Y F9 绝对Y变址
SBC $addr16,X FD 绝对X变址

注意:由于在做减法运算时,进位标志C会参与运算,所以在做减法前要先加指令 SEC,置进位标志

例:   //减法指令演示,目的是将寄存器A的内容减去地址2100的内容,结果送寄存器A

       2000: LDA #$21                    //立即数21送寄存器A

       2002:STA $2100                   //寄存器A的内容送地址2100

       2005: LDA #$22                    //立即数22送寄存器A

       2007:SEC                         //置位标志位C,注意:在做减法运算前一定要加该指令

       2008:SBC $2100                   //寄存器A的内容减去地址2100的内容

       200B: RTS

大家可以进入NCTOOLS,输入 A 2000,然后输入上面代码,然后 输入 G 2000,然后按R看寄存器A的值,是不是等于01呢?

 

例2:    //求二进制数的平方根

        程序目的:将地址2100的内容求得其平方根后,结果送地址2101,为方便计算,这里假设地址2100的内容为整数,方根也取整数

例如 若(2100)=19       (十进制的25)

    结果(2101)=05

    若(2101)=65       (十进制的101)

    结果(2101)=0A

 

    求方根方法:我们知道任何整数都有如下性质:

    1 * 1 = 1

    2 * 2 = 1 + 3

    3 * 3 = 1 + 3 + 5

    4 * 4 = 1 + 3 + 5 + 7

    ......

    N * N=1 + 3 + 5 + ...... + (2N-1)

    那么,我们可以把一个正整数X = N * N连续减去奇数 1, 3, 5, 7......(2N-1)直到结果为0或者不够减为止,所减去奇数的个数

就是这个正整数的整数平方根.

    在下面的程序里,我们将目标数连续减去地址F0的内容

    2000:LDA#$00       //初始化地址F0的内容为00

    2002:STA $F0

    2004:LDA $2100      //取目标数到寄存器A中

    2007:SEC

    2008:SBC $F0        //目标数减去地址F0的内容

    200A:BCC $2016      //不够减转结束,结果在地址F0中

    200C:INC $F0        //地址F0的内容加1,(06)为已减的奇数个数

    200E:SBC $F0        //和前面的减法指令合起来正好减去了奇整数

    2010:BEQ $2016      //减结果为0,转结束,结果在地址F0中

    2012:BCS $2008      //减结果>0,继续减

    2014:DEC $F0        //减结果<0,则从结果中扣除1

    2016:LDA $F0

    2018:STA $2101      //把最后结果送地址2101

    201B:RTS

   

 

3. INC--存储器单元内容增1  M+1→M

符号码格式 指令操作码 寻址方式
INC $addr E6 零页寻址
INC $addr16 EE 绝对寻址
INC $addr,X F6 零页X变址
INC $addr16,X FE 绝对X变址

  这个指令应该很好理解吧,就是把某个地址的内容加1,当然我们也可以用加法指令把某个地址加1,但大家可以看到,这里的指令所占用字节少

执行速度也较快.请看下面的比较:

  用加法指令把地址2100的内容加1

  2000:LDA $2100

  2003:CLC

  2004:ADC #$01

  2006:STA $2100

  2009:RTS

 

  所占字节数:10个

  用上面的指令把地址2100的内容加1

  2000:INC $2100

  2003:RTS

 

  所占字节数:4个

  一比较,大家就能发现谁占了上风吧!在对某个地址进行加1运算时,应该用INC指令.

 

4. DEC--存储器单元内容减1  M-1→M

符号码格式 指令操作码 寻址方式
DEC $addr C6 零页寻址
DEC $addr16 CE 绝对寻址
DEC $addr,X D6 零页X变址
DEC $addr16,X DE 绝对X变址

5. 寄存器X,Y加1减1

符号码格式 指令操作码 寻址方式
INX E8 隐含寻址
DEX CA 隐含寻址
INY C8 隐含寻址
DEY 88 隐含寻址