【问题标题】:Does AVR subtraction of equal numbers set the SREG C-flag?等数的 AVR 减法是否设置 SREG C 标志?
【发布时间】:2019-06-06 20:01:47
【问题描述】:

短背景: BRLO(如果较低则分支)指令被声明为 1. ... 如果 C 标志 == 1,则执行分支; 2. ... 如果 Rd

我的问题: 我将使用 4 位数字进行演示。假设 Rd = Rs = 3 = 0011。从上面的第 2 点来看,分支不应该发生。 CP 指令执行 Rd - Rr。如果我们使用二进制补码进行减法,我们有 0011 - 0011 = 0011 + 1100 + 0001 = 0000 带有 C 标志 = 1。因此上面的第 1 点与第 2 点相矛盾。

假设我错了:我在哪里搞砸了?

谢谢

【问题讨论】:

  • x-x 没有设置CF,因为没有溢出。是的,加法会设置它,并且在某些架构中,CF 的含义确实与减法相反。 AVR 不是其中之一。另请参阅指令集参考,其中说 "[CF] 如果 Rr 内容的绝对值大于 Rd 的绝对值,则设置;否则清除。"

标签: assembly avr integer-arithmetic


【解决方案1】:

简而言之,给出相同结果的操作并不总是等价的操作。因此,您的假设 0011 - 0011 = 0011 + 1100 + 0001 并且将具有相同的进位标志值 - 是错误的

虽然 A + (~B + 1) 给您的结果与 A - B 相同,但它并不相同,并且不会以相同的方式更新标志。

事实上,你忘记了一件事。在你的例子中:

0011 + 1100 + 0001 = 0000 - 错了。因为 0011 + 1100 + 0001 = 10000

在考虑二进制补码溢出时,您忘记了 A + (~B + 1) 等于 A - B。

现在您可以看到进位标志在这两种操作中是非常相反的。事实上,当 A - B 没有借位(下溢)时,A + ~B + 1 才会出现溢出(在第一次或第二次加法中)。

进行加法C标志时表示溢出发生,即从最左边的位开始执行。

即如果要添加:

  0110
+ 1101
  ----
 10011
  ^^^^ the result
 ^ the carry flag

也就是说,如果你对一个较长的数字进行加法,由几个寄存器组成,你必须在较高的部分加一。例如

 add r16, r18 // adds r18 to r16, C flag is set only when overflow happened
 adc r17, r19 // adds r19 to r18, and add one if C flag is set. updates the C flag by the overflow again
 // in result r17:r16 = r17:r16 + r19:r18

减法时,C标志表示从最左边的位开始借位,因此数字的高位应减一

 *  *  - borrow positions
  0110
- 1101
  ----
  0001
 ^ carry flag is set when borrowed at left from the leftmost positions.

在汇编程序中你有 sbc 指令,它将减法作为 sub 指令,但如果设置了进位标志,则结果减一

 sub r16, r18 // subtracts r18 from r16, C flag is set only when underflow happened
 sbc r17, r19 // subtracts r19 from r18, and subtracts one more if C flag is set. updates the C flag by the underflow again
 // in result r17:r16 = r17:r16 - r19:r18

所以,回答你的问题:当你从自身减去数字时,进位标志的值被清除,因为没有发生下溢。

AVR 架构具有简单的分支机制。它有 8 个标志位,每个分支指令只根据其中一位的值进行分支。

所以,BRLOBRCS 都是相同机器码的助记符,如果设置了进位标志,则会进行分支。仅当您从较低的无符号值中减去较高的无符号值时,才会设置进位标志。

如果要进行有符号比较,则必须使用BRLT 指令,该指令查看S 标志,等于标志NV 的异或。 N 标志在运算结果为负符号数时设置(设置高位)。 V 标志表示已发生签名溢出。它们的异或组合表示从较小的数字中减去较大的有符号数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 2015-03-17
    相关资源
    最近更新 更多