【问题标题】:JL instruction in MSP430MSP430 中的 JL 指令
【发布时间】:2018-03-07 17:34:52
【问题描述】:

给定 MSP430 中的代码:

     CLR  R6
     MOV  #5, R5                                  
L1:  DEC  R5
     CMP  #0, R5
     JL   L1
     INC  R6

我被告知执行后 R5 的值为 4 而不是 0。

这是 JL 指令特有的吗?

【问题讨论】:

  • CMP指令如何设置状态位? JL 对这些位采取什么行动?您是否阅读了手册中的 JL 条目?你到底有什么不明白的?
  • 我不明白为什么 JL 在第一次递减后会失败。我的理解是,第一次递减后,它会一直持续到 R5 为 0。但我被告知它在第一次递减后不会跳转到 L1。

标签: assembly embedded cpu-architecture msp430


【解决方案1】:

JL 是“如果小于则跳转”。

来自指令集:

JL : Jump to Label if (N .XOR. V) = 1 

因此,只有在设置了负标志或溢出标志(但不能同时设置两者)时才会发生跳转。

CMP 指令可以通过执行b - a(在本例中为R5 - 0)来设置其中任何一个-CMP #0, R5 只是一种测试R5 值的方法。

CMP 和 JL 一起表示 IF R5 < 0 GOTO L1

由于你已经设置为5,然后递减为4,它不会小于零,所以JL不会分支。

也许 JNZ 是有意的(“如果不为零则跳转”)或其同义词 JNE(“如果不等于则跳转”)。

     CLR  R6      ; R6 = 0
     MOV  #5, R5  ; R5 = 5                        
L1:  DEC  R5      ; R5 = R5 - 1

     CMP  #0, R5  ; if R5 - 0 ...
     JL   L1      ; ... is less than zero ... <-- This is never true
                  ; ... then goto L1 

     INC  R6      ; R6 = R6 + 1
                  ; Here R5 = 4, R6 = 1

还要注意 DEC 指令也设置了 N 和 V 标志,因此实际上不需要 CMP。

     CLR  R6      ; R6 = 0
     MOV  #5, R5  ; R5 = 5                        
L1:  DEC  R5      ; R5 = R5 - 1

     JNZ  L1      ; if R5 is not zero ... 
                  ; ... then goto L1   <-- This will loop until R5 == zero

     INC  R6      ; R6 = R6 + 1
                  ; Here R5 = 0, R6 = 1

【讨论】:

    【解决方案2】:

    参见手册中的这个例子:

    CMP  @R7,R6   ; Is R6 < @R7?
    JL   Label5   ; Yes, go to Label5
    ...           ; No, continue here
    

    在所有双操作数 MSP 指令中,第一个操作数是源,第二个是目标。此约定对于所有其他指令都更具可读性,但对于 CMP,这意味着将第二个操作数与第一个操作数进行比较。

    所以CMP #0, R5JL 检查 R5 是否小于零(事实并非如此)。

    为保证循环后R5为零,当R5不等于0时跳转,即JNE。 (并且CMP #0, xTST x 相同。)

    【讨论】:

      【解决方案3】:

      这是我认为其他答案中缺少的重要一点。正如 Clifford 指出的那样,如果 V xor N 为 1,则 JL 表示跳跃

      0x0005 - 0x0000

      减法是通过加法、反转和加一来完成的

      11111111111111111
       0000000000000101
      +1111111111111111
      ===================
       0000000000000101
      

      N为0,V为0

      N xor V 为 0 xor 0 即为 0

      JL 不应分支。

      N 为 0,V 为 0,Z 为 0,进位取决于架构,它可能保持 C = 1 不变,也可能反转它,因为这是一个减法,并认为它是借位 C = 0

      从评论看来,您希望它以 R5 = 0 退出循环,因此我们知道 R5 的标志将大于 0(我们可以假设)

      0x0000 - 0x0000

         11111111111111111
          0000000000000000
       +  1111111111111111
      ====================
          0000000000000000
      

      V 为 0,N 为 0,Z 现在为 1,C 为 0 或 1,具体取决于架构

      最容易使用的是如果不为零则跳转(如果未设置 z 标志则跳转),这也没有任何大于或小于的问题,因为您必须了解架构和从如果大于小于助记符,则文档适用于无符号数学或有符号数学,因为它会有所不同。例如,如果您查看 arm,您会看到它从已签名(同一指令的两个助记符/名称)中调出未签名。

      【讨论】:

      • 在汇编中编程时,文档并不总是清楚地说明减法是哪种方式,也不总是记录被测试的标志,当然只是盲目地选择如果大于则跳转,如果小于则跳转等,它比你想象的要低的几率很低 25%。有符号与无符号 a - b 或 b - a 只有一个组合是您想要的,其他 75% 是对您不起作用的组合。如果您觉得需要使用这些助记符(小于或大于变体),请进行研究,并停止并进行自定义实验。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-28
      • 2020-12-09
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      相关资源
      最近更新 更多