如何在没有XOR指令的CPU上进行异或

时间:2015-08-14 20:58:20

标签: assembly

这更像是一个有趣的问题。我正在研究SC61860 CPU,它是1987年夏普PC-1360掌上电脑的8位CPU(也用于PC-1401和1403)。它的指令集实际上并不包含异或。它有AND,OR,比较,减法和加法指令。

我尝试了一些ANDing和ORing值的变体来获得XOR会产生的结果,但没有运气。我希望避免比较,但看起来我没有选择。

如果您有兴趣,可以查看instruction set

顺便说一下,这个CPU非常适合学习装配。好的,简单的,足够慢(768kHz),机器语言明显快于使用BASIC内置的计算机;)我通常用C / C ++ / Java编程。装配一直呼吸着新鲜空气。

2 个答案:

答案 0 :(得分:11)

从布尔代数我们知道:

A XOR B = (NOT(A) AND B) OR (A AND NOT(B))

<强>更新: 感谢@Brett Hale,@ slebetman,因为CPU令人惊讶地不支持NOT指令,它可以通过算术否定和减法来模拟,假设2的补码为负数表示):

NOT(A) = (-1) - A

或者在负面表示不同的情况下,-1可以用相应的存储类型最大值替换(即8位寄存器为255或16位寄存器为65565)。

答案 1 :(得分:0)

油滑!谢谢,这非常有效。

9 XOR 11 = 2

a XOR b = (NOT(a) AND b) OR (a AND NOT(b))
        = ((255-9) and 11) or (9 and (255-11))
        = (246 and 11) or (9 and 244)    
        = 2 or 0
        = 2

这是使用8位寄存器的程序。要同时使用2个寄存器,例如ANDing,必须将P指向第二个寄存器。然后你可以[P]和A - &gt;警:

##############################################################################
## xor.asm
## perform a logical XOR operation on numA and numB and store to numC
## numC = numA XOR numB
##############################################################################

                $JR
                org     &C030

                jp     start

I_REG           equ     0               # Internal Registers
J_REG           equ     1
A_REG           equ     2
B_REG           equ     3
XL_REG          equ     4
XH_REG          equ     5
YL_REG          equ     6
YH_REG          equ     7
K_REG           equ     8
L_REG           equ     9
M_REG           equ     10
N_REG           equ     11
PORTC           equ     95

numA:           db      9
numB:           db      11
numC:           db      0

# EXAB          A <-> B 
# SBM           [P] - A -> [P] 
# ANMA          [P] and A -> [P] 
# ORMA          [P] or A -> [P]
# PUSH          push A onto the stack
# POP           pop A from the stack

start:          lp      B_REG           # point P to the B register
                lidp    numA            # (not a & b)
                ldd                     # A = numA
                lib     255
                sbm                     # B = 255 - numA
                lidp    numB            # A = numB
                ldd
                anma                    # B = 255-numA & numB 
                exab                    # swap A and B to store result on the stack 
                push                    # push A (result) to the stack

                lidp    numB            # (a & not b)
                ldd
                lib     255
                sbm                     # B = 255 - numB, B = not b
                lidp    numA
                ldd
                anma                    # B = numA & (255 - numB)
                pop                     # grab the first result
                orma                    # B = final result
                lidp    numC
                exab
                std                     # numC = numA XOR numB

end:            rtn