2013-10-26 3 views
5

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

Вот пример, который я не мог понять:

enter image description here

Я знаю, что внутри сегмента данных, есть адреса, начиная с 0x10010000,0x10010020 и т.д..

И я знаю, что внутри каждого адреса имеется 8 полей памяти, каждая из которых имеет 32 бит.

Теперь, что я не понимаю, как и почему var2 внутри адреса 0x10010010? str1 находится внутри адреса 0x10010003, потому что мы зарезервировали 3 бита для var1.

Последнее, что именно директива .align' doing? when I tested it in Mars4, it only shifted the data into the next memory field when I used выровнять 3` и вверх, но я действительно не понимаю.

Прошу прощения, если это очень запутывающие парни, я отчасти отчаялся здесь.

ответ

9

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

Поле .ASCIIZ может быть размещено в любом месте, так как строка считывается по одному байту за раз. Так что положить его на 0x10010003 в порядке.

Поле .WORD должно быть выровнено с кратным 4. Поэтому его нельзя поместить в 0x1001000E, следующее доступное местоположение после строки. Ассемблер намеренно смещает значение и оставляет два байта неиспользованным. К следующему адресу, который кратен 4, 0x10010010.

Директива .ALIGN - это способ переопределить правила выравнивания по умолчанию. Следующее поле после директивы будет выровнено с кратным 2 на мощность n, где n - значение .ALIGN. В вашем случае это pow (2, 3) = 8 байт.

Это то, что вы видите, без директивы .ALIGN поле .HALF будет храниться в 0x10010014. Не кратно 8, поэтому он перемещается в 0x10010018.

Приведенный пример в противном случае является искусственным, нет очевидной причины использовать директиву .ALIGN здесь, так как .HALF требует только aligment для множественного числа 2, поэтому сохранение его в 0x10010014 было бы в порядке.

+1

Набрал мой ответ на телефоне, пока его не было ... ваш бы избавил от необходимости другого. – gnometorule

+0

Спасибо всем за ваши ответы! Вопрос: Как 0x10010010 является кратным 4? – Sobiaholic

+0

0x10010010 = 2^28 + 2^16 + 2^4, который умножается на 4. Если расчет не имеет для вас смысла, пожалуйста, прочитайте снова шестнадцатеричные числа. – gnometorule

3

Некоторые директивы сборки подразумевают, что данные сохраняются вровень, что означает начало с адреса, который является мощностью двух. Напомним, первый несколько конвенций в MIPS:

(1) "слово" составляет 4 байта (иногда будете видеть, что определяется как 2 байта),

(2) полуслова (.half) являются 2 байты и

(3) .asciiz null завершает строку (как в C).

Используя это, вы уже объяснили, как сохраняются var1 и str1. Почему буфер из 2 пустых байтов перед var2? Поскольку он объявлен как .word и (в соответствии с (1) выше), он будет сохранен, начиная с места памяти, который будет кратным 4. Если бы вы объявили его .half, у вас не было бы 2 пустых байтов между str1 и var2.

var2 объявлен .half - это 16-разрядный (2-байтовый) адрес, который вписывается в один. Однако перед объявлением его выравнивание изменяется на 3. Теперь проверьте первое предложение: это мощность вы поднимаете 2 до; поэтому мы фактически выравниваем до 8. Это означает, что до переопределения переменные будут помещаться как объявленные, но дополнительно их первоначальное место хранения должно быть кратно 8. Следовательно, ассемблер вставляет 4 пустых байта для хранения var3 с кратным 8.

Смежные вопросы