8085-进位标志的奇怪行为

2024-03-02

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

我渐渐熟悉了ADC说明和下面的说明似乎没有按照我想要的方式工作。

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

继续我之前的评论:这是函数中的一个错误_eef_inst_func_add_with_carry_i in src/8085-instructions.cGNUSim8085 源代码。这是当前的源代码master分支,离开 GitHub https://github.com/GNUSim8085/GNUSim8085(修订版 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));

See 第 326 行以下这里 https://github.com/GNUSim8085/GNUSim8085/blob/ebbda5941092781acf1f60dd1c2b95828cbf3d2e/src/8085-instructions.c.

我们暂时忽略:

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

该错误是由于eef_data_t是 的别名guint8,以及检查是否的代码either添加data or data_1,即data + sys.flag.c,转换回eef_data_t,累加器溢出,并相应地设置进位标志。

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

8085-进位标志的奇怪行为 的相关文章

随机推荐