Думаю, я понимаю вашу озабоченность. Регистр флагов получает результат операции, поэтому имеет смысл, что AND, OR, XOR все влияют на флаг Zero, флаг Sign и флаг четности. Это все прямые свойства результата. Но операции не являются арифметическими, поэтому Carry не является естественным свойством.
Я думаю, что ответ лежит на самом ALU. В качестве программистов мы рассматриваем ALU как многофункциональный блок. Вы даете ему значение и операцию и выполняет эту операцию на флажках установки аккумулятора в качестве побочного продукта. Внутренне мы подозреваем, что для каждой операции имеется отдельная схема: добавление, вычитание и/или xor.
На самом деле это больше похоже на многофункциональную функцию каждого бита, которая может быть изменена для выполнения желаемых операций. На высоком уровне мы видим это с добавлением vs add with carry. Внутренне единственная разница в этих инструкциях заключается в том, используется ли флаг переноса при выполнении добавления. Точно так же вычесть - это не что иное, как добавление двух дополнений к числу. Так что вычесть только имеет некоторую внешнюю замену операнда и использует ту же схему добавления.
Теперь рассмотрим, как мы делаем дополнение на одном бите. Игнорируя уведомление переноса, 0 + 0 = 1, 0 + 1 = 1 + 0 = 1 и 1 + 1 = 0. А как насчет нести? (0 + 0) = перенос (0 + 1) = перенос (1 + 0) = 0 и перенос (1 + 1) = 1.
Признать эти функции? Несущий два бита - это их И. Результатом добавления двух бит является их XOR. Если вы расширите эту идею еще немного, вы увидите, как простая схема может добавить два бита вместе с переносным вводом и создать результирующий бит и вывод переноса. Цепочка 8 из них вместе, и вы добавляете числа.
Если вы проектировали процессор, вы также можете заметить, что вы можете получить XOR почти бесплатно. XOR просто добавляет два числа вместе, но останавливает перенос от бит к бит. Подобные ярлыки могут вытащить значение AND, которое вы обычно получаете из расчета переноса, и я уверен, что есть какой-то другой трюк, чтобы найти OR там. Детали здесь очень важны, потому что дизайнеры Z-80 не использовали логики AND и XOR, но логику транзисторов с сыром, что еще более гибко в том, что она может производить из схемы.
Во всяком случае, теперь есть выбор. Наш XOR обнуляет перенос между каждым битом. Как насчет 8-го бита? Ну, извините, мы тоже должны его обнулить. В противном случае бит переноса будет символом AND знаковых битов, который, по-видимому, смущает и раздражает программистов ассемблера и не будет очень полезен. Но если мы ноль, несущий бит, как мы сделали все остальные, то у нас есть симпатичная симметричная схема, и результат ясен и однозначен. И, я подозреваю, легче обнулить значение, чем игнорировать его.
Итак, давая ноль переносить, мы сможем сэкономить несколько транзисторов. И этот побочный эффект пригодится в таких операциях, как «OR A, A» или «AND A, A», которые в противном случае не делают много. Теперь Z-80 унаследовал это поведение от 8080, поэтому на самом деле это был выбор дизайнера 8080, а не Z-80. Вы можете видеть, что они думали об этом в наборе команд, поскольку они давали нам две операции, непосредственно влияющие на перенос: SCF - установить флаг переноса в 1 и CCF - дополнять флаг переноса. Они явно избегали давать нам «четкий флаг переноса», поскольку «OR A, A» уже делает это бесплатно. Таким образом, весь бизнес сохраняет целую инструкцию. И, мы можем только предположить, они рассуждали, что обнуление флага переноса на логической операции не является большим препятствием для программирования. В большинстве случаев вы либо делаете логический расчет, либо арифметический, так что логические операции, связанные с переносом, не имеют большого значения. Очевидно, что другие разработчики процессоров не согласились, но это правильный выбор.
Нижняя линия: очистка переноса является естественным результатом схемы, которую, по мнению дизайнеров 8080, было полезным побочным эффектом, чтобы сохранить и предпочесть, чтобы это было скорее, чем добавить схему для ее подавления.
Подробную информацию см. В разделе Z-80 ALU operates internally и 8085 ALU internals.
Я до сих пор не понимаю, что вы подразумеваете под «как». Вот как это работает, по определению. Это тоже не странно, аппаратно. – harold
Но это не имеет смысла для меня, или я просто не понимаю. Я имею в виду, когда вы «LD A, 0' влияет на регистр A, а не на регистр B, а не на регистр F, потому что это регистр, который я выбрал для выполнения операции. Итак, почему исключение «XOR A»? –
_ "как выполнение операции над некоторым регистром (A) влияет на другой регистр (F)" _. Это обычное, часто желаемое свойство. 'F' - это, в конце концов, регистр _flags_. Например, после выполнения 'cp' вы можете узнать, были ли операнды равными (Z установлен), а после' add' вы можете узнать, был ли сгенерирован перенос и т. Д. – Michael