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

[逻辑运算指令]

1.AND--寄存器与累加器相与,结果送累加器  A∧M→A

符号码格式 指令操作码 寻址方式
AND ($addr,X) 21 先变址X后间址
AND $addr 25 零页寻址
AND #$data 29 立即寻址
AND $addr16 2D 绝对寻址
AND ($addr),Y 31 后变址Y间址
AND $addr,X 35 零页X变址
AND $addr16,Y 39 绝对Y变址
AND $addr16,X 3D 绝对X变址

  逻辑与的主要功能是对目的操作数的某些位置0,或测试某位的状态

例1: 屏蔽地址2100的高四位,即将地址2100的高四位清零

     2000:LDA $2100

     2003:AND #$7F    (7F转化为二进制:0000 1111)

     2005:STA $2100

     2008:RTS

    所以我们可以知道,我们要使地址2100的高四为为0,只要使操作数的高四位为0,低四位为1,即操作数为0000 1111

然后再把地址2100的内容送寄存器A,把A的内容和0000 1111进行逻辑与运算,那么寄存器A的高四位自然就为0,由于操作数

低四位为1,所以寄存器A的低四位不变.

 

例2: 测试地址2100的第2位的状态,如果第2位=0,那么把00送寄存器X,否则把01送寄存器X

     2000:LDA $2100

     2003:AND #$04    (04转化为二进制:0000 0100)

     2005:CMP #$04

     2007:BNE $200C

     2009:LDX #$01

     200B:RTS

     200C:LDX #$00

     200E:RTS

 

    在这个程序中,我们要测试第2位的状态,只要让它与 0000 0100 进行逻辑与运算,若第2位为0,那么结果一定为0

如果第二位为1,那么由于操作数的第2位也为1,所以结果为0000 0100,即十六进制的04,所以我们可以判断结果是不是04

如果是04,那么说明第2位为1,否则为0.

    随便说个笑话,我们数字电路的老师告诉我们这样的口诀记住逻辑与的用法,那就是 "见0出0,全1出1"

    

2.ORA--寄存器与累加器相或,结果送累加器  A∨M→A

符号码格式 指令操作码 寻址方式
ORA ($addr,X) 01 先变址X后间址
ORA $addr 05 零页寻址
ORA #$data 09 立即寻址
ORA $addr16 0D 绝对寻址
ORA ($addr),Y 11 后变址Y间址
ORA $addr,X 15 零页X变址
ORA $addr16,Y 19 绝对Y变址
ORA $addr16,X 1D 绝对X变址

    先告诉大家哪个不登大雅之堂的口诀 "见1出1,全0出0"

     逻辑或的功能主要是对目的操作数的某些位置1

例1: 使地址2100的高4位置1

     2000:LDA $2100

     2003:ORA #$F0   (F0的二进制:1111 0000)

     2005:STA $2100

     2008:RTS

  这里我就不解释为什么这样做了,大家可以想一下.

 

3.EOR--寄存器与累加器相异或,结果送累加器  A≮M→A

符号码格式 指令操作码 寻址方式
EOR ($addr,X) 41 先变址X后间址
EOR $addr 45 零页寻址
EOR #$data 49 立即寻址
EOR $addr16 4D 绝对寻址
EOR ($addr),Y 51 后变址Y间址
EOR $addr,X 55 零页X变址
EOR $addr16,Y 59 绝对Y变址
EOR $addr16,X 5D 绝对X变址

  先告诉大家哪个不登大雅之堂的口诀 "相同出0,不同出1"

  异或的功能主要就是求补码,加密等.

例1: 求地址2100的内容的反码

     2000:LDA $2100

     2003:EOR #$FF

     2005:STA $2100

     2008:RTS

    先说明下异或是怎么回事,什么是 "相同出0,不同出1"

   这里我们要把立即数7F,40进行异或运算,过程是这样的

   1.先把7F,40转化为二进制形式

   2.然后如果相同的位的值都不相同,那么该位为1,否则为0

(HEX) 7F   (BIN) 0 1 1 1 1 1 1 1    (EOR)


(HEX) 40   (BIN) 0 1 0 0 0 0 0 0

(HEX) 3F   (BIN) 0 0 1 1 1 1 1 1

 

   所以我们要求反码,只要将该数和FF进行异或运算就可以了.

 

例2: 把地址3000-30FF的数据加密与解密

    先说明下为什么异或运算可以对数据进行加密,异或运算有一个特性:

    一个操作数(这里设为D1),和另外一个操作数(这里设为D2)进行异或运算,结果为D3

   表达式是这样的 D1 EOR D2 = D3

   然后如果我们将D3 再和D2进行异或运算,结果一定为D1,这就是加密的依据.

   所以我们要对某段数据进行加密时,只要使改段数据均和某个数进行异或运算,解密时再把加密的数据再和该数进行

异或运算即可,这里的某个数我们成为密匙,也就是说,一个人要解密,他必须得到密匙才能解密.

   当然实际运用时,我们可以搞的稍微复杂些,就比如下面的例子,以寄存器X的内容作为对象进行异或.

 

   加密程序如下:

    2000:LDX #$50              //这里50就是密匙,不过这里的密匙不是不变的,每异或一次就加1

    2002:LDY #$00              //计数器Y初始化为00

    2004:INX                   //寄存器X的内容加1,即每异或一次,寄存器X的内容就加1

    2005:TXA                   //寄存器X的内容发送给寄存器A

    2007:EOR $3000,Y           //寄存器A的内容和地址[3000+Y]的内容进行异或运算

    200A:STA $3000,Y           //结果仍然送回原地址

    200D:INY                   //计数器Y的值加1

    200E:BNE $2004             //当全部加密完,程序结束,否则继续

    2010:RTS

   

    解密程序如下:

    2100:LDX #$50              //解密时,必须知道加密时X寄存器的初值,否则无法解密

    2102:LDY #$00              //计数器Y初始化为00

    2104:INX                   //寄存器X的内容加1,即每异或一次,寄存器X的内容就加1

    2105:LDA $3000,Y           //地址[3000+Y]的内容送寄存器A

    2108:STX $F0               //X寄存器的内容送地址F0,为下面的指令做好准备,因为没有和寄存器X进行异或运算的指令

    210A:EOR $F0               //寄存器A的内容和地址F0即寄存器X的内容进行异或

    210C:STA $3000,Y           //结果送回原地址

    210F:INY                   //计数器Y的值加1

    2110:BNE $2104             //当全部解密完,程序结束,否则继续

    2112:RTS

 

    由上面的程序可以知道,加密程序的密匙是可变的,但是变化规律很明显,就是一直加1,解密程序和加密程序几乎是一样的.

当然,这样的加密程序是不管用的,讲这个程序的目的只是抛砖引玉,为了说明EOR在加密中的运用.