Сама этикетка нигде не хранится. Это просто символический адрес ассемблера / компоновщика. Код операции инструкции jump j again
сохраняет фактический результирующий адрес в виде числа.
Компоновщик склеивает вместе все объектные файлы, объединяя все символы в объектных файлах и заполняя правильные относительные адреса + создавая таблицу перемещения для загрузчика ОС, создавая исполняемый файл.
ОС после загрузки исполняемого файла также загрузит таблицу перемещения, изменит / заполнит инструкции, работающие с абсолютными адресами в соответствии с фактическим адресом, по которому был загружен двоичный файл, затем выбросит таблицу перемещения и выполнит код.
Таким образом, метки являются для программиста просто «исходным кодом», псевдонимом для определенного фиксированного адреса памяти, чтобы избавить программиста от подсчета фактических размеров кода операции команд и вычисления смещений перехода в адресах переменных головы или памяти.
Вы можете проверить "файл списка" из вашего ассемблера (часто /l
переключатель) при компиляции какого-либо источника сборки, чтобы увидеть фактический машинный код произведенных байтов (нет для меток).
Ваш код "задачи" при компиляции в 0x00400000
выглядит следующим образом (я установил для этих add
выполнение t1 = t1 + t1, чтобы там было что-нибудь):
Address Code Basic Source
0x00400000 0x01294820 add $9,$9,$9 4 add $t1,$t1,$t1
0x00400004 0x01294820 add $9,$9,$9 5 add $t1,$t1,$t1
0x00400008 0x11090004 beq $8,$9,0x00000004 6 beq $t0, $t1, next
0x0040000c 0x1509fffc bne $8,$9,0xfffffffc 7 bne $t0, $t1, again
0x00400010 0x01294820 add $9,$9,$9 8 add $t1,$t1,$t1
0x00400014 0x01294820 add $9,$9,$9 9 add $t1,$t1,$t1
0x00400018 0x01294820 add $9,$9,$9 10 add $t1,$t1,$t1
0x0040001c 0x08100000 j 0x00400000 11 next: j again
Как вы можете видеть, каждая реальная инструкция создает 32-битное значение, которое иногда называют «кодом операции» (кодом операции), это значение отображается в столбце «Код». В столбце «Адрес» указано, где это значение хранится в памяти, когда исполняемый файл загружен и готов к выполнению. В столбце «Основные» показаны инструкции, разобранные обратно из кодов операций, а в последней позиции находится столбец «Источник».
Теперь посмотрим, как условные переходы кодируют значение относительного перехода в 16 бит (код операции beq $8, $9
равен 0x1109
, а остальные 16 бит 0x0004
- это 16-битное расширенное значение знака «сколько переходить»). Это значение означает количество инструкций, удаленных от «текущей позиции», где current - это адрес следующей инструкции, т.е.
0x0040000c + 0x0004 * 4 = 0x0040001c = target address
* 4, потому что в MIPS каждая инструкция имеет длину ровно 4 байта, и адресация памяти работает по байтам, а не по инструкции.
То же самое и со следующим bne
, сам код операции 0x1509
, смещение 0xfffc
, то есть -4. =>
0x00400010 + (-4) * 4 = 0x00400000
Абсолютный переход использует другую кодировку, это 6-битный код операции 0b000010xx
(xx - это два бита адреса, хранящиеся в первом байте вместе с кодом операции j
, в этом примере они равны нулю), за которым следует адрес 26b, разделенный на четыре 0x0100000
, потому что каждая инструкция должна начинаться по выровненному адресу, поэтому было бы напрасно кодировать два младших бита, они всегда будут 00
. 0x100000 * 4 = 0x00400000
... Мне лень проверять, как это работает на MIPS, но я думаю, что j
определяет биты 2-27, 0-1 - это нули, а 28-31 скопированы из текущего pc
, может быть? Обеспечение способности ЦП работать с полным диапазоном адресов 4 ГиБ, но, вероятно, есть какой-то особый способ переключения между разными «банками» (верхние 4 бита pc
)). Я не уверен, я никогда не писал код для MIPS, поэтому Я не читал спецификации процессора.
В любом случае, если вы скажете, что again:
находится на 0x10010020
, все это можно пересчитать, чтобы получить функциональный код, готовый к выполнению на 0x10010020
(хотя этот j
будет сложным, вам нужно будет точно знать, как общий адрес составляется, если копируются старшие 4 бита что ли).
Кстати, реальный процессор MIPS выполняет отложенное ветвление (т. Е. Следующая инструкция после перехода выполняется всегда, в то время как условие оценивается, и переход происходит после следующей инструкции), и я думаю, что pc
, используемый для вычисления целевого адреса, также 1 инструкция «позже», поэтому правильный код для реального MIPS будет иметь это beq
перед вторым add
, но относительное смещение все равно будет 0x0004
. :) Просто а? Если это не имеет для вас смысла, проверьте настройки MARS (эмуляция отложенного ветвления отключена по умолчанию, чтобы не сбивать с толку учащихся) и поищите в Google более подробное объяснение. Симпатичный маленький забавный процессор, MIPS. :)
person
Ped7g
schedule
05.03.2017