Инструкции MIPS имеют длину 32 бита, и поэтому адреса используются программой.
Это означает, что инструкция lw
не может указать полный 32-разрядный адрес как немедленный. Проще говоря, инструкция lw $t, var
недействительна (ожидайте для очень немногих случаев).
В самом деле, его кодирование
lw $t, offset($s)
1000 11ss ssst tttt iiii iiii iiii iiii
Где I биты показывают, что только 16 битов используются для указания адреса (и о том, что базовый регистр всегда должен быть указан, в конечном счете $zero
регистр может использоваться).
Так ассемблер делает этот трюк: всякий раз, когда вы используете lw $t, var
он собирает эту инструкцию в два инструкций, один, что нагрузить верхние 16 бит адреса в $at
и lw
, которые используют $at
в качестве базового регистра с более низкие 16 бит адреса в качестве смещения.
lui $at, ADDR_H #ADDR_H is ADDR >> 16
lw $t, ADDR_L($at) #ADDR_L is ADDR & 0xffff
Заметим, что так как lw
считывает из $at
+ ADDR_L конечный адрес, используемый в ADDR_H < < 16 + ADDR_L = ADDR. Как и ожидалось.
Существует тонкость, указал Mike Spivey (ему большое спасибо), смотрите ниже
Этот вид инструкций, которые не отображаются непосредственно в ISA, называются псевдо- инструкция. Регистр $at
зарезервирован для ассемблера точно для их реализации.
В MARS можно отключить инструкции псевдо отключив Настройки> Разрешения продлен (псевдо) инструкции и формат.
Хотя программирование без псевдо-инструкций будет очень раздражать довольно быстро, стоит хотя бы раз сделать это, чтобы полностью понять архитектуру MIPS.
Mike Spivey правильно отметил, что 16-битовое смещение является непосредственным входа продлен перед добавлением в базовый регистр.
Это требует коррекции значения, которое я назвал ADDR_H
, в случае, если ADDR_L
оказывается отрицательным при интерпретации номера дополнения 16-разрядного двоичного кода.
Если это правда, ADDR_H
должен быть увеличен.
Общая формула для ADDR_H
может быть исправлена, чтобы ADDR_H = ADDR >> 16 + ADDR[15]
где ADDR[15]
обозначает значение бита 15 из ADDR
(который является знаковым битом ADDR_L
.
'0x10010000' случается адрес' x'. – Jester
О, ОК. – Max