Генерация адреса инструкции с использованием сегмента кода и указателя инструкции

Считайте, что адресом сегмента кода будет FE00, а указателем инструкции - ABBE. Сдвиг сегмента кода на 4 бита и добавление указателя инструкции приводит к дополнительному переносу. Как мы представляем сгенерированный адрес?


person FlameAlchemist    schedule 13.01.2020    source источник
comment
Линейные адреса 8086 имеют ширину 20 бит; вам нужно 2 регистра и adc перенос из младших 16 в старшие 4 бита.   -  person Peter Cordes    schedule 13.01.2020
comment
@Peter Cordes: На самом деле, поскольку 286 линейных адресов в (Real / Virtual) 86 Mode имеют ширину 21 бит, так как старший бит может выполнять младшие 20 бит. Таким образом A20 (21-я адресная строка).   -  person ecm    schedule 26.01.2020


Ответы (1)


Считайте, что адресом сегмента кода будет FE00, а указателем инструкции - ABBE. Как мы представляем сгенерированный адрес?

Либо вы представляете адрес как

  • 0FE00h:0ABBEh, его сегментированная форма с использованием двух 16-битных чисел, разделенных двоеточием, и всегда (сегмент - двоеточие - смещение)
  • 00108BBEh, его линейная форма с использованием одного 32-битного числа

Независимо от вашего выбора, на 8086 всегда потребуется регистр размером 2 слова.

"указатель инструкции - это смещение в сегменте памяти размером 64 КБ, которое начинается с линейного адреса, полученного в результате умножения значения в регистре CS сегмента кода на 16 (то же самое, что и сдвиг влево 4 раза)."

Вычисление линейного адреса может быть выполнено неэффективно (но легко для понимания) следующим образом:

mov     ax, 0FE00h  ; The code segment
mov     dx, 16
mul     dx          ; "shifting the code segment by 4 bits"
add     ax, 0ABBEh  ; "adding the instruction pointer"
adc     dx, 0       ; Taking care of the additional carry

Этот линейный адрес 00108BBEh использует 2 регистра AX и DX. Регистр AX будет содержать младшую часть 8BBEh, а регистр DX будет содержать самую значительную часть 0010h. Если вам нужно обратиться ко всей паре регистров, вы делаете это как DX:AX. Итак, highWord - двоеточие - lowWord.

В отличие от нотации seg: off, это всего лишь одно 32-битное число, разделенное на 2 регистра, без перекрывающихся значений мест. Младший бит старшей половины имеет разрядное значение 2 ^ 16, когда мы говорим о плоском 32-битном (или 20-битном) числе, а не об адресе seg: off.

person Sep Roland    schedule 19.01.2020
comment
Обычно группы регистров, которые образуют единое более широкое значение, описываются от наиболее значимого регистра до наименее значимого регистра. Таким образом, вы обычно видите DX: AX (старшее слово: младшее слово). Документация Intel также в значительной степени приняла это соглашение. - person Michael Petch; 19.01.2020
comment
@MichaelPetch Вы правы. Должно быть, я подумал, как значение хранится в памяти ... - person Sep Roland; 19.01.2020
comment
Если бы вы действительно собирались запустить это (особенно на 8086), вы бы избегали mul и вручную выполняли сдвиг влево с повышенной точностью. Например, извлеките верхние 4 бита в нижнюю часть другого регистра по одному в цикле с shl / adc dx,dx или с mov dl, ah; shr dl, 4 (186); mov dh, 0. Или, если у вас есть эффективные смены (не 1 отсчет за такт) mov dx, ax; shr dx, 12 - person Peter Cordes; 20.01.2020