//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在加密中的运用.