MIPS32: перевод псевдо-инструкции ld - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь понять, как работает псевдоинструкция в MIPS32 "ld".Я использую симулятор MARS для проверки кода.Когда MARS собирает следующий код

    .data
LEN:
    .word 12
.text
ld $6, LEN

, он говорит в основном коде

lui $1, 0x00001001
lw $6, 0x00000000($1)
lui $1, 0x00001001
lw $7, 0x00000004($1)

Кажется, что инструкции lw делают все необходимое: он загружает 32 регистра по указанному адресу 0x00000000 в регистр $ 6и следующие 32 бита в следующий регистр.

Инструкция lui мне кажется бесполезной.Это даже делает то же самое дважды, почему?Он используется в качестве смещения для инструкции lw, но он должен иметь дважды одинаковое значение, иначе мы получим не 64-битный адрес памяти, а два «случайных» 32-битных?

Кто-нибудь может мне помочь, гдемоя ошибка в мышлении?Вероятно, это совсем не то, что я думаю ...

1 Ответ

0 голосов
/ 18 мая 2018

LEN находится внутри .data сегмента со смещением +0, которое является адресом 0x0000100100000000 (начало сегмента .data).

Таким образом, инструкции lw извлекают данные изадрес 0x0000100100000000+0 и 0x0000100100000000+4, который вычисляется из $1 + 0 и $1 + 4.

lui устанавливает это значение в $1.

Дважды, поскольку ассемблер MARSсвоего рода «тупой», производящий собственные инструкции MIPS фиксированным способом, не оптимизируя особые случаи, когда значение уже находится в регистре $1.Некоторые из псевдо-инструкций могут быть даже реализованы более эффективным способом, если вы проверите их все, это не значит, что MARS производит наиболее оптимальный вариант.

Вы можете теоретически удалить вторую lui в данном конкретном случае.случай, не влияющий на результат, но удаление первого lui заставит lw получить доступ к совершенно другой области памяти (так как регистр $1 будет содержать другое значение).


EDIT: btwВы зарезервировали только один .word для LEN, поэтому второй lw извлекает значение вне этого слова, обычно в более сложном источнике, который будет ошибкой / оплошностью.

И если вы зарезервируете LEN после того, как какая-то другая .data память уже использовалась, за lui будет следовать ori, чтобы поместить в $1 полный адрес, включая младшие 16 бит.Это одна из редких оптимизаций MARS: удалить ori «адреса загрузки», когда младшие 16 битов равны нулю.

Я думаю, ld будет выглядеть как lui, ori, lw, lui, ori, lw, то естьбыть еще более избыточным.

...