Место хранения меток MIPS

В MIPS при использовании инструкции перехода мы используем метку.

again: nop
    $j again

Поэтому, когда мы достигаем инструкции перехода, мы используем метку again, чтобы показать, куда идти, и используется значение фактического адреса. Я хотел знать, где хранится метка снова. Это означает, что, скажем, nop хранится по адресу 0x00400000, а инструкция перехода находится по адресу 0x00400004. Где же тогда again хранится, откуда MIPS знает, что again указывает на 0x00400000? Хранится ли он в области динамических данных карты памяти? Это карта памяти, которую я предоставил для MIPS

Я также включил вопрос, который вызвал эту путаницу, ниже для справки.

Укажите шестнадцатеричный код объекта для следующих инструкций ветвления (be, bne) и перехода (j).

... # some other instructions
again:  add ... # there is an instruction here and meaning is insignificant
    add ... # likewise for the other similar cases
    beq    $t0, $t1, next
    bne  $t0, $t1, again
    add ...
    add ...
    add ...
next:   j   again

Предположим, что метка снова находится в ячейке памяти 0x10 01 00 20. Если вы считаете, что у вас недостаточно информации для генерации объяснения кода.


person ali.salemwala    schedule 05.03.2017    source источник
comment
Это решает ассемблер или компоновщик. Его вообще нет в исполняемом файле.   -  person Jester    schedule 05.03.2017


Ответы (3)


Каждая метка соответствует уникальному адресу в памяти. Итак, в вашем примере и в соответствии с тем, что вы заявили, если инструкция nop существует по адресу 0x00400000, тогда again будет соответствовать (не точка - подробнее об этом через секунду) тому же адресу.

Ярлыки могут существовать как в текстовом, так и в сегменте данных. Однако в вашем примере метка отображается в сегменте .text:. Таким образом, он представляет собой адрес инструкции, а не переменной.

Вот важное различие:

Ярлыки являются частью большинства ISA, чтобы сделать написание ассемблера проще для людей. Однако важно помнить, что сборка не окончательная форма кода. Другими словами, в двоичном представлении ваша метка больше не будет похожа на метку.

Итак, вот что произойдет:

Ассемблер распознает адрес памяти, связанный с каждой инструкцией метки. Сохраним наш рабочий пример 0x00400000. Затем в каждой инструкции перехода он будет использовать этот адрес для замены метки в коде операции. Poof, никаких ярлыков и определенно никаких указателей (что означало бы, что у нас будет другое место в памяти, где хранится адрес памяти).

Конечно, сам адрес памяти соответствует месту в текстовом сегменте в вашем примере, потому что он соответствует инструкции.

Проще говоря, ярлыки существуют, чтобы облегчить нам жизнь. Однако после сборки они преобразуются в фактический адрес памяти инструкции / переменной, которую они пометили.

person Faris Sbahi    schedule 05.03.2017
comment
Итак, когда в вопросе говорится «Предположим, что метка снова находится в ячейке памяти 0x10 01 00 20.», что это означает? Спасибо за объяснение, многое прояснилось. - person ali.salemwala; 06.03.2017
comment
Это означает, что метка обозначает инструкцию, которая хранится в этой ячейке памяти. И добро пожаловать! - person Faris Sbahi; 06.03.2017
comment
Но затем, согласно предоставленной мне карте памяти, этот адрес (0x10010020) находится в области динамических данных (для стека и кучи). Текст находится в другом диапазоне. Означает ли это, что с вопросом возникла проблема, или инструкции можно хранить в стеке / куче? - person ali.salemwala; 06.03.2017
comment
Инструкции не могут быть сохранены в сегменте динамических данных. Это должно быть опечатка. - person Faris Sbahi; 06.03.2017

Сама этикетка нигде не хранится. Это просто символический адрес ассемблера / компоновщика. Код операции инструкции 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
comment
Итак, когда в вопросе говорится «Предположим, что метка снова находится в ячейке памяти 0x10 01 00 20.», что это означает? Спасибо за объяснение, многое прояснилось. - person ali.salemwala; 06.03.2017
comment
Это означает, что символ again является псевдонимом для значения 0x10010020, а 32-битное значение является адресом, по которому будет загружен следующий байт, определенный в источнике после метки again:. В ответ добавлю краткий пример листинга ... MIPS, хм, не уверен, что буду управлять MIPS, попробую с MARS, если нет, то добавлю x86, так как принцип везде одинаковый. - person Ped7g; 06.03.2017
comment
собственно я сам тоже использую МАРС. Итак, если в вопросе говорится, что 0x10010020 - это адрес, на который указывает again, но текстовые инструкции не могут храниться там в соответствии с картой памяти, в вопросе есть опечатка? - person ali.salemwala; 06.03.2017
comment
Я не уверен, что то, что вы имеете в виду, нельзя удерживать там, может быть, этот вопрос не соответствует тому определению машины, к которому вы привыкли, и он имел в виду машину, которая имеет отображенную память? 0x10010020 является допустимым 32-битным значением, где-то после первых 256 МБ памяти, поэтому для машины с 512 МБ ОЗУ и отображением плоской памяти это может быть действительный адрес. Или для машины с процессором, который позволяет отображать виртуальную память, тогда карта памяти определяется ОС, а не жестким ограничением HW. - person Ped7g; 06.03.2017
comment
Я еще немного проверил MARS ... так что 0x10010000 - это общий адрес для сегмента .data, и карту памяти нельзя свободно менять (есть 3 разных предустановки). Также, если я попытаюсь собрать инструкции в .data сегменте, машинный код не будет создан (это причуда симулятора MARS, обычные ассемблеры так не работают, они с радостью будут создавать машинный код из этих инструкций внутри сегмента .data) ... Итак возможна опечатка. Опять же, если бы у вас была совершенно другая операционная система MIPS, в которой использовалась бы другая карта памяти, тогда вопрос действителен и разрешим. - person Ped7g; 06.03.2017
comment
@ Ped7g Я не понимаю, в чем разница между смещением в столбце кода (последние 16 бит) и полем адреса в столбце Basic. В вашем примере они такие же, но в моем домашнем задании они дали нам этот сегмент кода: i.imgur.com /vnTxN8Z.jpg и спросите нас, какой адрес цикла, как я могу определить? - person Avishay28; 23.11.2017
comment
@ Avishay28 а что в вашем коде отличается? Я вижу код операции 14210009 для bne $1,$1,9 ... т.е. +9 против +9. Итак, это 9 слов впереди от текущей следующей инструкции. Следующая инструкция находится по адресу 0x400014, + 9 * 4 = 0x400038 = адрес loop. Я не понимаю, что изменилось в моем примере. Не могли бы вы дать подробный обзор, что это такое? - person Ped7g; 23.11.2017
comment
@ Ped7g посмотрите на строку 34, операцию J. Мне нужно определить адрес цикла только по этой строке, используя описанный вами метод, я получаю неверный результат: 0040000c + 000e * 4 = 0x00400044 - person Avishay28; 23.11.2017
comment
@ Avishay28, потому что j вычисляет целевой адрес иначе, чем переходы по ветвям, не используя адрес следующей инструкции, а только 4 старших бита PC, и беря 26 бит из операционного кода инструкции (а не 16). Этот ответ выглядит хорошо выполненным (первое нажатие Google на вычисление адреса инструкции MIPS j, попробуйте иногда, это отличная поисковая система): https://stackoverflow.com/a/9795721/4271923 - person Ped7g; 23.11.2017
comment
@ Avishay28 теперь я вижу, что у меня это есть даже в моем собственном ответе, объясненном выше Абсолютный прыжок использует другую кодировку, ... ??? Вам было слишком долго читать, или описание неправильное / трудное для понимания? - person Ped7g; 23.11.2017
comment
@ Ped7g Я не понимаю, почему ты так зол. В любом случае спасибо, я проверю, что вы отправили. - person Avishay28; 23.11.2017
comment
Давайте продолжим это обсуждение в чате. - person Ped7g; 23.11.2017

Преобразование метки в соответствующий адрес выполняется ассемблером кода или симулятором MIPS, который вы используете, например, MARS - это симулятор MIPS, поэтому MARS выполняет это преобразование. MARS найдет для вас адрес лейбла.

person Sayed Abdullah Qutb    schedule 06.04.2019