【问题标题】:8085- Strange behaviour of Carry flag8085-进位标志的奇怪行为
【发布时间】:2018-12-03 13:50:49
【问题描述】:

我正在使用 GNUSim8085 (训练器上的结果也相同)

我对@9​​87654322@ 指令越来越熟悉,而下面的指令似乎并没有按我想要的方式工作。

stc  ;to make sure carry is set

mvi a,00h  
mvi b,0ffh          

adc b

hlt

我希望设置进位标志,因为我们要添加 11111111+00000000+00000001 ,因此显然会产生进位但未设置进位标志。为什么会这样。你能解释一下吗?

还有为什么在下面的代码中生成了进位而不是在上面的代码中:

stc  ;to make sure carry is set

mvi a,7dh  ; 7dh  ==    01111101
mvi b,c8h  ; c8h  ==    11001000        

adc b

hlt

【问题讨论】:

  • (按照那里的答案建议,尝试使用另一个模拟器)
  • 我在trainer上也试过了,结果还是一样
  • @helb 一些编译器和汇编器要求所有整数文字都以数字开头,因此您需要添加前导 0,即使使用 h 后缀也是如此。
  • 这显然是一个错误。如果结果不适合 8 位,则 8085 手册要求设置 CY。 另外,如果 a b 颠倒了。 (a=0ffh, b=@ 987654331@) 即加法在模拟器中是不可交换的,这不仅与规范相矛盾,而且与底层数学本身相矛盾……

标签: assembly simulator 8085


【解决方案1】:

继续我之前的评论:这是 GNUSim8085 源代码的 src/8085-instructions.c 中的函数 _eef_inst_func_add_with_carry_i 中的一个错误。这是来自master 分支off of GitHub 的当前源代码(rev. 88a604043a2b7f153ff97e2c3026145814f7fc39):

eef_data_t data_1;

/* I'm not sure abt the new code
 * Old code:
 if (op == '+')
 data_1 = data + sys.flag.c;
 else
 data_1 = data - sys.flag.c;
*/
data_1 = data + sys.flag.c;

/* check for flags */
sys.flag.c = 0; 
sys.flag.c = (_eef_is_carry (sys.reg.a, data, op)
              || _eef_is_carry (sys.reg.a, data_1, op));

lines 326 ff. here

让我们暂时忽略:

  • 冗余分配sys.flag.c = 0;
  • 指向与 SBB 指令相关的早期错误的注释

这个错误是由于eef_data_tguint8的别名,并且代码检查是否或者添加datadata_1,即data + sys.flag.c,转换返回eef_data_t,累加器,溢出,并相应地设置进位标志。

如果data == 0xff,那么data_1 == 0,因为data + sys.flag.c == 0x100,但是结果在赋值中被转换回一个8位无符号整数,丢失了最高有效位。然后,eef_is_carry 用于检查0 + 0xff0 + 0 是否溢出,两者都不是。因此,进位位被清除。但实际添加的当然是0 + 0x100,肯定会溢出。

我坚持我之前的说法,即这是一个错误。尽管根据公认的长加法规则在数学上应该有进位,但不设置进位标志是不合逻辑的。 8085 规范没有描述这种特殊情况。而且,即使例外是有效的,你不同意它应该有详细的记录吗?

最重要的是,这种行为的 ADC 在常见用例中根本无法可靠地工作。硬件级别的 ADC 指令甚至存在的原因是相对于使用比较和分支的丑陋替代方案来提高多字加法的速度(并减少代码大小)。如果 ADC 没有正确检测所有进位条件,则该命令在实现通用多字加法时是不充分的,甚至是无用的。在我看来,与根本没有相比,有一个损坏的 ADC 是没有意义的。 (正如我之前所说,由于这个错误,ADC 也违反了交换律a + b == b + a。)

也就是说,您指出您的教练板表现出相同的行为。我没有 8085 教练板,你没有说你有哪一个,所以我无法重现这种行为。我认为您的教练板可能与 GNUSim8085 有相同的错误。根据板上是否有 8085 克隆,这甚至有可能是 GNUSim8085 的“错误兼容错误”的不幸案例。然而,这只是目前的所有猜测。

【讨论】:

  • 看起来与 Assembly ADC (Add with carry) to C++ 类似的错误,这是 add-with-carry 的另一个 C 实现。当有 2 个输入 + 一个进位时,单个比较不足以获得进位。 (尽管在这里看起来他们正试图通过将 a+bdata_1 + carry_in 的进位检查组合在一起来解决问题)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
  • 2013-07-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多