【问题标题】:How to XOR on a CPU that doesn't have an XOR instruction如何在没有 XOR 指令的 CPU 上进行异或
【发布时间】:2015-08-14 20:58:20
【问题描述】:

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

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

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

顺便说一句,这个 CPU 非常适合学习组装。很好,很简单,而且足够慢(768kHz),机器语言比使用 BASIC 内置的计算机要快得多;)我通常用 C/C++/Java 编程。大会呼吸了新鲜空气。

【问题讨论】:

    标签: assembly


    【解决方案1】:

    从布尔代数我们知道:

    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)。

    【讨论】:

    • 好吧,除了 CPU 也没有 NOT 指令之外,没有理由不这样做。
    • @Ross Ridge 好吧,这太糟糕了:) 我稍后会更新关于如何用算术运算模拟它的答案。
    • NOT(A) = - 1 - A ,即:255 - A65535 - A 用于 8 / 16 位寄存器。
    • @BrettHale:假设 2s 补码时要小心。这些带有奇怪指令集的奇怪 CPU 中的一些有时使用有符号整数而不是 2s 补码。因此,如果 -1 实际上等于 128 而不是 255,则使用 255 - A 会更安全。
    【解决方案2】:

    光滑!谢谢,效果真的很好。

    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 -> P:

    ##############################################################################
    ## 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
    

    【讨论】:

      猜你喜欢
      • 2016-09-29
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-11
      相关资源
      最近更新 更多