Assembly 比较3位并发送1位输出

Assembly 比较3位并发送1位输出,assembly,8051,Assembly,8051,对于一个问题,我们需要比较两个端口的三位,然后使用另一个端口的三位作为输出。如果第一个端口中存储的三位等于第二个端口中的三位,则输出的第一位设置为1。如果大于,则p2.1设置为高。如果小于p2.2,则设置为高。我的问题是,通过这种方式以及使用门来解决这个问题是可能的(和/或,但这需要一点一点地解决,这是一种痛苦)。有没有更简单的方法 ORG 000H MOV A, P1; x is p1 and y is p3 MOV R5, P3; MOV P2, #0; CJNE A,05H, CHECK;

对于一个问题,我们需要比较两个端口的三位,然后使用另一个端口的三位作为输出。如果第一个端口中存储的三位等于第二个端口中的三位,则输出的第一位设置为1。如果大于,则p2.1设置为高。如果小于p2.2,则设置为高。我的问题是,通过这种方式以及使用门来解决这个问题是可能的(和/或,但这需要一点一点地解决,这是一种痛苦)。有没有更简单的方法

ORG 000H
MOV A, P1; x is p1 and y is p3
MOV R5, P3;
MOV P2, #0;
CJNE A,05H, CHECK; if it isn't equal we go to check routine
SETB P2.0; Equal output set high
SJMP HERE; End progam
CHECK: 
MOV A, P1
SUBB A, P3 ; Subtract
JC HM; 
SETB P2.1; 
SJMP HERE;
HM: SETB P2.2; 
SJMP HERE; 

HERE: CLR A;
END; 
  • 将输出寄存器设置为1(假设它将相等)。这叫R
  • 比较这两个端口
  • 分支如果等于7-完成
  • 分支(如果进位到6)-更大
  • 左移1位
  • 左移1位
  • 将R存储在P2中

  • 这种直通逻辑对于汇编程序编程来说是不可或缺的。

    要仅比较端口中的三位,首先需要屏蔽其他位,否则将比较所有八位。然后,您只需使用一次比较(无论是SUBB还是CJNE),即可确定一个端口的位是否等于、小于或大于另一个端口。这两条指令将两个操作数相减,并根据结果设置进位标志(C)。如果它们相等,那么SUBB将0存储在A中,您可以使用JZ/JNZ测试这一点。在CJNE的情况下,如果它们相等,则指令不会跳转。在这两种情况下,当它们不相等时,您可以使用JC/JNC测试进位标志,以确定它们是否小于或大于。如果A寄存器小于另一个操作数,则这些指令设置进位标志


    如果使用SUBB,请不要忘记此指令“使用借阅进行减法”使用进位标志作为输入。这意味着您需要在使用前清除进位标志(CLR C)

    这里有一个从每个输入端口接受三个任意位的解决方案

    我假设如下:

    如果P0=P1,则设置P2.0

    如果P0>P1,则设置P2.1

    设置P2.1其他

        org    0000H
    Init:
        MOV     P2DIR, 00H             ; Make P2 an output
    
    ReadAndMask:
        MOV     A,     P0              ; read port P0
        ANL     A,     #13H            ; your P1-mask
        MOV     R0,    A               ; Save in R0
    
        MOV     A,     P1              ; read port P1
        ANL     A,     #0A1H           ; your P1-mask
    
        CJNE    A,     00H,    NotEq   ; compare A with R0
    
    Equal:
        MOV     P2,    #01H            ; Set P2.0 clear the rest
        SJMP    ReadAndMask            ; Repeat forever
    
    NotEq:
        JC      P0Greater              ; Check carry to see if P0 > P1
    
    P0Greater:
        MOV     P2,    #02H            ; Set P2.1 clear the rest
        SJMP    ReadAndMask            ; Repeat forever
    
    P0NotGreater:
        MOV     P2,    #04H            ; Set P2.2 clear the rest
        SJMP    ReadAndMask            ; Repeat forever
    
        end
    

    对不起,你说的移位是什么意思?课堂上还没有讨论过。你用的是哪种芯片?8051?是的,8051微控制器。@Peter。Risc机器(如8051)每个周期有一条指令,但对于任何其他架构,ADC都比移位慢得多,并且指令更短(无操作数或短操作数),因此通常最好使用它。另外,我还想说明除了偶尔不间断的case-without-a-break之外,在其他语言中很少见的fall-through代码。@Mike:是的,说明好的分支布局的总体要点是好的。我习惯于现代x86 CPU,其中跳转非常昂贵:P.在x86上,
    adc
    比Broadwell之前Intel微体系结构上的
    add
    稍微贵一点。Broadwell/Skylake上的单uop(利用Haswell为FMA引入的3个依赖uop)。AMD的m-op一直都是如此。无论如何,在x86上,
    adc
    可能是一种节省代码大小和UOP的有趣方法。(
    cmp
    /
    jcc
    可以将宏融合到单个uop中,但每个解码组只有一个宏融合…)。无论如何,与8051有点不同:p在进行比较之前,您需要将其中一组位移位,以匹配另一组位的对齐方式。