【问题标题】:Comparing 3 bits and sending a 1 bit output比较 3 位并发送 1 位输出
【发布时间】:2016-04-28 11:36:02
【问题描述】:

对于一个问题,我们需要比较两个端口的三位,然后使用另一个端口的三位作为输出。如果存储在第一个端口中的三位等于第二个端口中的三位,则输出的第一位设置为 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; 

【问题讨论】:

    标签: assembly 8051


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:
      1. 将输出寄存器设置为 1(假设它将相等)。称之为 R。
      2. 比较两个端口。
      3. 如果等于 7 则分支 - 完成。
      4. 如果进位到 6 - 更大则分支
      5. R 左移 1 位
      6. R 左移 1 位
      7. 将 R 存储在 P2 中

      这种直通逻辑是汇编程序编程不可或缺的一部分。

      【讨论】:

      • 很抱歉,您说的转移是什么意思?它还没有在课堂上讲过。
      • 你用的是哪个芯片? 8051?
      • 是的,一个 8051 微控制器。
      • @彼得。 Risc 机器(如 8051)每个周期有一条指令,但对于任何其他架构,ADC 比移位慢得多,并且指令更短(无操作数或短操作数),因此通常最好使用它。另外,我想说明在其他语言中很少见的失败代码,除了偶尔的 case-without-a-break。
      • @Mike:是的,说明良好的分支布局的总体观点是好的。我已经习惯了跳跃成本高昂的现代 x86 CPU:P。在 x86 上,adc 在 Broadwell 之前的英特尔微架构上比 add 稍贵。 Broadwell/Skylake 上的单个 uop(利用 Haswell 中为 FMA 引入的 3 依赖 uop)。 AMD 一直是 1 m-op。无论如何,在 x86 上,adc 可能是一种节省代码大小和微指令的有趣方式。 (cmp/jcc 可以宏融合成单个微指令,但每个解码组只能进行一个宏融合...)。无论如何,与 8051 有点不同:P
      【解决方案3】:

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

      我假设如下:

      如果 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
      

      【讨论】:

      • 在进行比较之前,您需要移动其中一组位以匹配另一组位的对齐方式。
      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2014-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多