Game Boy: Какова цель инструкций, которые ничего не изменяют (например, AND A)?

Я работал над эмулятором Game Boy и заметил, что существуют определенные коды операций, которые никогда не изменяют никаких значений, например LD A, A, LD B, B и т. д., а также AND A. Первые, очевидно, ничего не меняют, поскольку загружают значения регистров в те же регистры, а поскольку AND сравнивается с A, AND A всегда будет возвращать A. Есть ли какая-то цель для этих операций, или они по сути такие же, как NOP после каждого цикла?


person Zach Brantmeier    schedule 17.10.2014    source источник
comment
Я предполагаю, что они существуют по той же причине, по которой вы можете написать mov eax, eax в x86: не стоило усложнять пространство кодирования, чтобы использовать эти кодировки для чего-то полезного. (Я недостаточно знаком с Game Boy или z80, чтобы сказать, есть ли у этих инструкций какие-либо скрытые микроархитектурные побочные эффекты, извините.)   -  person Jeffrey Bosboom    schedule 17.10.2014
comment
Это восходит к процессору 8008 1970 года. Простота была важна, в нем было всего 3500 транзисторов. Более поздние 8080 и Z80 копировали дизайн набора инструкций. В них нет никакой цели, только для того, чтобы упростить логику декодера инструкций.   -  person Hans Passant    schedule 19.10.2014


Ответы (3)


Как Джеффри Босбум и Ханс Пассант указал на их комментарии, причина в простоте. Точнее аппаратная простота.

Инструкции LD r,r' копируют содержимое исходного регистра (r') в целевой регистр (r). LD r,r' коды операций имеют следующую форму:

        -------------------------------
BIT    | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
        -------------------------------
OPCODE | 0 | 1 |     r     |     r'    |
        -------------------------------

Регистры назначения и источника могут принимать следующие значения:

 -----------
| BIT | REG |
 -----------
| 111 |  A  |
 -----------
| 000 |  B  |
 -----------
| 001 |  C  |
 -----------
| 010 |  D  |
 -----------
| 011 |  E  |
 -----------
| 100 |  H  |
 -----------
| 101 |  L  |
 -----------

Чтобы реализовать эти инструкции на аппаратном уровне, нам просто нужен мультиплексор, который получает биты 0-2 для выбора исходного регистра, и другой мультиплексор, который получает биты 3-5 для выбора регистра назначения.

Если вы хотите проверить, указывают ли биты 0–2 и биты 3–5 на один и тот же регистр, вам придется добавить больше логики в ЦП. И, как мы все знаем, в 80-х ресурсы были более ограниченными: P

Обратите внимание, что инструкции по загрузке, такие как LD A,A, LD B,B, LD C,C, LD D,D, LD E,E, LD H,H и LD L,L, ведут себя как NOP. Однако AND A и OR A НЕ ведут себя как NOP, поскольку они влияют на регистр флагов, и их выполнение может изменить внутреннее состояние машины.

person GabrielOshiro    schedule 20.10.2014
comment
Работая с точки зрения программного обеспечения, легко упустить из виду аппаратное обеспечение, которое должно было быть установлено в исходной системе. Как раз то, что я искал, спасибо. - person Zach Brantmeier; 22.10.2014
comment
На самом деле (по крайней мере, на Z80 процессор геймбоя - это не Z80, может быть, Z80 или 8080, как только ... отсутствуют многие функции Z80), единственное исключение - (HL) с LD, комбинация LD (HL), (HL) не существует и вместо этого это означает HALT (это совершенно другое). Но ссылка (HL) в любом случае немного особенная, даже если она находится среди обычных кодов операций LD r1, r2 block os. - person LGB; 31.10.2014

Такие инструкции, как LD A,A и AND A, могут выглядеть как NOP, но они также могут изменять флаги процессора и использоваться для проверки значения регистра.

Обязательно внимательно изучите документацию по набору инструкций на наличие таких побочных эффектов.

person HBP    schedule 19.10.2014
comment
AND A — это идиоматический способ сравнения с нулем, если память не изменяет; это один байт, а не два, и в результате меньше циклов. - person Tommy; 31.10.2014
comment
Однако LD r,r' не меняет флаги. - person Jongware; 05.06.2016

В инструкции AND A (а также OR A) на самом деле есть цель есть -- она ​​устанавливает флаг Z, когда A равен нулю, и сбрасывает в противном случае. Поэтому для этой цели часто используются как AND A, так и OR A.

person lvd    schedule 08.11.2014
comment
Они также безоговорочно очищают флаг переноса, что полезно, если вы используете его для возврата результата (например, функция, которая возвращает значение, но сигнализирует об ошибке или исключении, устанавливая перенос). - person Simon Sellick; 16.03.2015