Загружать байты/полуслова из памяти в MIPS

Меня просят создать сегмент данных, используя директивы .byte и .word для хранения значений 0x01, 0x02, 0x03, 0x04 в виде байтов и значения 0x12345678 в виде слова. Мой код будет:

.data
    b1: .byte 0x01
    b2: .byte 0x02
    b3: .byte 0x03
    b4: .byte 0x04
    w1: .word 0x12345678

Затем я хочу использовать lbu,lhu и lw для загрузки в $t0,$t1,$t2 значений: 0x01, 0x0201 и 0x12345678 соответственно.

Что я делаю для этого:

    lbu $t0,b1  #this works
    lhu $t1,0(b2)   #this doesn't work, gets an error
    lw $t2,w1   #also works

Моя ошибка исключение и невыровненный адрес в inst/data fetch: 0x10010001. Как загрузить более 1 байта в качестве полуслова? Является ли мое объявление переменных в сегменте данных неправильным? Может быть, я хочу что-то вроде:

byte_array: .byte 0x01,0x02

Спасибо всем за помощь.

Забавный факт: если бы вы использовали процессор MIPS32r6, он бы работал без сбоев. Эта доработка ISA добавила требование, чтобы невыровненная загрузка работала (возможно, медленно, возможно, даже через перехват помощи из вспомогательного кода). en.wikipedia.org/wiki/MIPS_architecture#MIPS32/MIPS64 - что позволило удалить LWL/LWR (невыровненные части слова загрузки слева/справа)

Peter Cordes 23.04.2022 15:05
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
1
36
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы пытаетесь загрузить полуслово (lhu), которое объявлено как .byte. Это несоответствие размера, которое приводит к ошибке, которую вы получаете.

Но процессору важно не несоответствие размеров, а выравнивание. Таким образом, если вы хотите загрузить половину слова (два байта), они должны начинаться с четной границы байта, что не относится к вашей настройке данных.

lhu $t0, b1 будет работать, как и lhu $t0,b3, и lhu $t0,w1, потому что эти данные находятся по четным адресам. Однако b2 и b4 находятся по нечетным адресам.

Компилятор C не позволит вам выполнить загрузку с несоответствием размера в первую очередь без серьезного приведения, которое вернет вас к этим невыровненным ошибкам в MIPS. Кроме того, процессор x86 допускает несогласованный доступ, хотя в некоторых случаях он будет медленнее, чем выровненные эквиваленты.

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

Вы также можете изменить выравнивание, вставив дополнение — один дополнительный байт, вставленный между b1 и b2, изменит выравнивание b2, позволяя загружать b2 и b3 с помощью lhu. Поскольку w1 объявлен как .word, ассемблер знает, что его нужно выровнять по словам, поэтому вставка этого одного байта между b1 и b3 приведет к тому, что w1 потребует 3 байта дополнительного заполнения выравнивания (которое ассемблер предоставит из-за того, что объявление данных .word является использовал).

Когда вы используете такое несоответствие размера, также возникает проблема порядка следования байтов. Симуляторы MIPS будут использовать тот же порядок следования байтов, что и базовый процессор, поэтому вы, как правило, увидите поведение с прямым порядком байтов при загрузке 2 байтов. Если вы объявите два .bytes вместо одного .half, вам придется выбрать порядок байтов.

Re: странное поведение классических ассемблеров MIPS (таких как MARS), вставляющих отступ до в метку w1: из-за того, что они видят после нее (директива .word): см. Встроенный ассемблер симулятора MARS MIPS выравнивает больше, чем требуется? для подробностей/сравнения с обычными современными ассемблерами, такими как GAS.

Peter Cordes 23.04.2022 14:59

MARS написан на Java и всегда имитирует MIPS с прямым порядком байтов независимо от того, на какой ISA он работает. SPIM работает так, как вы описываете, имитируя MIPS с тем же порядком байтов, что и центральный процессор. (написано на С)

Peter Cordes 23.04.2022 15:22

Спасибо, я понял теорию, но я до сих пор не могу понять, как я буду решать свой вопрос. Как бы я загрузил 2 байта как полуслово, даже если бы я выровнял? И как бы я выровнялся в первую очередь?

user1512676872 23.04.2022 15:30

Следующие директивы выполняют выравнивание: .half, .word,.float, .double и, наконец, .align.

Erik Eidt 23.04.2022 19:29

Другие вопросы по теме