Z80 16-битная инструкция загрузки и порядок следования байтов

Я пишу эмулятор ZX Spectrum на C# "для удовольствия" (думаю, я уже жалею, что начал).

Я знаю, что у Z80 порядок следования байтов с прямым порядком байтов, поэтому в ОЗУ сначала хранится младший байт.

На что я не могу найти однозначного ответа, так это на то, как он ведет себя с 16-битной инструкцией LD.

Например:

LD BC, 0x1234

После этого B содержит 0x12, а C содержит 0x34 или наоборот?

Итак, после вышеизложенного, если я выполню:

LD A, 0x56
LD (BC), A

Будет ли память 0x1234 или 0x3412 содержать 0x56?

Было бы неплохо, если бы кто-нибудь мог дать ссылку на надежный источник.

Есть другая пара регистров... HL... Работает так же... Угадайте, что означают H и L...

Selvin 04.02.2023 16:11

Вы написали инструкцию так, как ее отображает дизассемблер, или вы написали ее на ассемблере. Он использует «естественный» порядок, людям нравится их старший байт слева и наименее значимый справа. Та же история с парами регистров, у BC самый значащий регистр слева. Однако ваш эмулятор видит 0x01 0x34 0x12. Little-endian, 0x34 стоит первым. Только интерфейс шины памяти имеет детальный порядок байтов.

Hans Passant 04.02.2023 16:55

Значения в исходном коде asm являются значениями, а не кодировками; они используют обычный первый порядок старшей значащей цифры.

Peter Cordes 04.02.2023 17:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
117
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Является ли таблица производителя надежным источником? Руководство пользователя Z80 Ну и естественно в памяти после опкода сначала 0x34 потом 0x12

У меня есть это руководство... в нем просто сказано: "При выполнении инструкции LD HL, 5000h, пара регистров HL содержит 5000h". Не очень понятно.

Stevo 04.02.2023 16:27

На вопрос можно было бы ответить на странице 46 / 47 руководства пользователя, где описывается, как кодируется ld de,0659h, к сожалению, рисунок 37 был испорчен и вместо этого показывает and 7 :-)

Stefan Drissen 05.02.2023 22:30
Ответ принят как подходящий

Порядок байтов вступает в игру только тогда, когда мы разбиваем 16-битное значение на две 8-битные части, и есть выбор подходов, что происходит, когда такое 16-битное значение хранится в памяти, например:

  • С кодированием непосредственных инструкций в инструкциях, таких как ld bc, 0x1234: просмотрев отдельные байты машинного кода для этой инструкции, мы увидим 0x01 0x34 0x12, сохраняя 0x1234 в порядке байтов с прямым порядком байтов.

  • С 16-битным значением в качестве данных в памяти и просмотром отдельных байтов в памяти требуется порядок байтов, поэтому используйте прямой порядок байтов.

Однако, если пара регистров BC загружена со значением 0x1234, то это адрес памяти, с которым будет работать косвенное использование BC. В этом нет проблемы порядка следования байтов, поскольку в этом сценарии мы не рассматриваем отдельные байты.

Теперь, если вы хотите знать, как регистр BC составляется из B и C, нам нужно знать, какой из них является старшим, а какой — младшим.

Из руководства:

PUSH BC - это PUSH B, затем C

Таким образом, это означает, что в памяти стека будет значение из C, затем значение из B по адресу +1 больше, чем там, где хранилось C. Поскольку 16-битные данные в памяти хранятся с использованием прямого порядка байтов, мы можем сделать вывод, что C — это младший порядок, а B — старший порядок BC 16-битной пары регистров.

Таким образом, BC равно B * 256 + C. Заметим, однако, что это просто по определению, но на самом деле не идет к порядку байтов — поскольку нет «адресации» отдельных байтов, нет и другого порядка, как в памяти (из-за того, что память имеет оба адреса и значения).

Однако выбор высокого и низкого не меняет того, что вместе они содержат значение 0x1234, как в наших примерах.

Кажется, это имеет смысл, спасибо за четкое объяснение.

Stevo 04.02.2023 18:50

Если вы когда-нибудь сомневаетесь, иногда самый простой способ — проверить это самостоятельно. Итак, эмуляторы не всегда точны, но если у вас нет настоящего оборудования, они — ваш лучший вариант. Для чего-то подобного вы можете доверять почти всем эмуляторам, чтобы сделать это правильно.

puppydrum64 09.02.2023 17:41

@ puppydrum64, это хороший комментарий, но он больше подходит для ОП, чем для меня.

Erik Eidt 09.02.2023 17:42

Упс, я прокомментировал не тот пост!

puppydrum64 09.02.2023 17:43

Другие вопросы по теме