Продолжая мой предыдущий комментарий: Это ошибка в функции _eef_inst_func_add_with_carry_i
в src/8085-instructions.c
исходного кода GNUSim8085.Вот текущий исходный код из ветви master
, с 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
Ошибка вызвана тем, что eef_data_t
является псевдонимом guint8
, а код проверяет, является ли или добавлением data
или data_1
, чтоdata + sys.flag.c
, преобразуется обратно в eef_data_t
, в аккумулятор, переполняется и соответственно устанавливается флаг переноса.
Если data == 0xff
, то data_1 == 0
, потому что data + sys.flag.c == 0x100
, но результат преобразуетсявернуться к 8-битному целому числу без знака в присваивании, потеряв самый старший бит.Затем eef_is_carry
используется для проверки переполнения либо 0 + 0xff
, либо 0 + 0
, - ни один из случаев .Следовательно, бит переноса очищается.Но фактическим дополнением, конечно, является 0 + 0x100
, которое определенно переполняется.
Я поддерживаю свое предыдущее утверждение, что это ошибка.Нелогично оставлять флаг переноса неустановленным, несмотря на то, что математически должен быть перенос, согласно признанным правилам длительного сложения.Спецификация 8085 не описывает такого особого случая.И, даже если исключение было действительным, разве вы не согласны с тем, что оно должно быть хорошо задокументировано?
Самое главное, что АЦП, который ведет себя так, просто не работает надежно в общих случаях использования.Причина, по которой инструкции АЦП даже существуют на аппаратном уровне, заключается в увеличении скорости (и уменьшении размера кода) дополнений из нескольких слов по сравнению с безобразной альтернативой использования сравнений и ветвлений.Если АЦП не правильно определяет все условия переноса, то команда является недостаточной и даже бесполезной для реализации общего сложения из нескольких слов.Нет никакого смысла иметь сломанный АЦП, по сравнению с ним вообще, на мой взгляд.(Как я уже говорил ранее, из-за этой ошибки, АЦП также нарушает закон коммутативности a + b == b + a
.)
Тем не менее, вы указали, что на вашей доске тренера такое же поведение.У меня нет тренировочной доски 8085, а вы не сказали, какая у вас, поэтому я не могу воспроизвести это поведение.Я думаю, что возможно, ваша плата тренера имеет ту же ошибку, что и GNUSim8085.В зависимости от того, есть ли на плате клон 8085, даже возможно, что это неудачный случай «ошибки совместимости ошибок» с GNUSim8085.Это, однако, все спекуляции на данный момент.