8085-进位标志的奇怪行为 [英] 8085- Strange behaviour of Carry flag

查看:118
本文介绍了8085-进位标志的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用GNUSim8085 (培训师的结果也一样)

我对ADC指令很熟悉,下面的指令似乎无法按照我想要的方式工作.

I was getting familiar wih ADC instruction and the instructions below doesnt seem to work the way i want.

stc  ;to make sure carry is set

mvi a,00h  
mvi b,0ffh          

adc b

hlt

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

I expected the carry flag to be set because we are adding 11111111+00000000+00000001 , so that would obviously yield a carry but the carry flag is not set. Why is this working this way. Can you please explain this.

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

Also why is carry generated in the below code and not in the above code:

stc  ;to make sure carry is set

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

adc b

hlt

推荐答案

继续我之前的评论:这是GNUSim8085源代码的src/8085-instructions.c中的函数_eef_inst_func_add_with_carry_i中的错误.以下是master分支关闭GitHub 的当前源代码(版本88a604043a2b7f153ff97e2c3026145814f7fc39):

Continuing from my previous comment: It is a bug in the function _eef_inst_func_add_with_carry_i in src/8085-instructions.c of the GNUSim8085 source code. Here is the current source code from the master branch, 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));

...

请参见第326页及以下.这里.

让我们暂时忽略:

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

该错误是由于eef_data_tguint8的别名,并且代码检查了 是否添加了datadata_1(即data + sys.flag.c)而进行了转换回到eef_data_t,回到累加器,并相应地设置进位标志.

The bug is due to eef_data_t being an alias of guint8, and the code checking whether either the addition of data or data_1, which is data + sys.flag.c, converted back to an eef_data_t, to the accumulator, overflows, and setting the carry flag accordingly.

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

If data == 0xff, then data_1 == 0 because data + sys.flag.c == 0x100, but the result is converted back to an 8-bit unsigned integer in the assignment, losing the most significant bit. Then, eef_is_carry is used to check whether either 0 + 0xff, or 0 + 0 overflows, neither of which is the case. Therefore, the carry bit is cleared. But the actual addition, of course, is 0 + 0x100, which definitely overflows.

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

I stand by my previous claim that this is a bug. It is illogical to leave the carry flag unset despite the fact that there should be a carry, mathematically, according to the acknowledged rules of long addition. The 8085 specification describes no such special case. And, even if the exception was valid, don't you agree it should be well-documented?

最重要的是,像这样的ADC根本无法在常见的用例中可靠地工作.甚至在硬件级别上存在ADC指令的原因是,相对于使用比较和分支的丑陋选择,它可以提高多字添加的速度(并减小代码大小).如果ADC无法正确检测所有进位条件,则该命令将不足以实现通用的多字加法.在我看来,与根本没有ADC相比,ADC损坏是没有意义的. (正如我之前所述,由于此错误,ADC还违反了可交换性定律a + b == b + a.)

Most importantly, an ADC that behaves like this simply does not work reliably in common use cases. The reason why ADC instructions at the hardware level even exists is to increase speed (and reduce code size) of multi-word additions relative to the ugly alternative of using comparisons and branching. If ADC does not correctly detect all carry conditions, then the command is insufficient, and even useless, in implementing generic multi-word addition. There is no point in having a broken ADC, compared to none at all, in my opinion. (As I stated previously, due to this bug, the ADC also violates the law of commutativity a + b == b + a.)

也就是说,您指出您的训练台表现出相同的行为.我没有8085培训板,您也没有说是哪一个,所以我无法重现这种现象.我认为您的训练板可能与GNUSim8085有相同的错误.取决于板上是否有8085克隆,这甚至有可能是GNUSim8085的错误兼容的错误"案例.但是,这只是所有猜测.

That said, you pointed out that your trainer board exhibits the same behavior. I do not have an 8085 trainer board, and you did not say which one you have, so I cannot reproduce this behavior. I think it is possible that your trainer board has the same bug as GNUSim8085. Depending on whether there is an 8085 clone on the board, it is even possible that this is an unfortunate case of "bug for bug compatibility" with GNUSim8085. This is however, all speculation at this point.

这篇关于8085-进位标志的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆