1 курс 2 семестр / лекции / Лекция 5 Адресация и опер память — копия
.pdfЛекция 5. Адресация и оперативная память процессора.
Вопросы:
1.Режимы адресации 2.Карта оперативной памяти.
3.Трансляция и запуск программы.
1.Режимы адресации
Вархитектуре MIPS используются пять режимов адресации: 1. Регистровый (англ.: register-only),
2.Непосредственный (англ.: immediate),
3.Базовый (англ.: base),
4.Относительно счетчика команд (англ.: PC-relative)
5.Псевдопрямой (англ.: pseudo-direct).
1,2,3 режимы (регистровый, непосредственный и базовый) определяют способы чтения и записи операндов.
4 и 5 режимы (адресации относительно счетчика команд и псевдопрямой режим) определяют способы записи счётчика команд (англ.: program counter, PC).
1.1.Регистровая адресация.
При регистровой адресации адреса регистров используются для всех операндовисточников и операндов-результата. Все инструкции типа R используют именно такой режим адресации, например, инструкция add $s1,$s2,$s3 $s2 и $s3 – источники; $s1 - результат
1.2. Непосредственная адресация.
При непосредственной адресации в качестве операндов наряду с регистрами используют 16-битные константы (непосредственные операнды). Этот режим адресации используют инструкции типа I, такие как сложение с константой, например инструкции
1.3.Базовая адресация.
Инструкции для доступа в память, такие как загрузка слова (lw) и сохранение слова (sw), используют базовую адресацию. Эффективный адрес операнда в памяти вычисляется
путем сложения базового адреса в регистре rs и 16-битного смещения с расширенным знаком, являющегося непосредственным операндом. Например:
Lw $s1, 03 ($s0) # загрузка в регистр s1 из памяти по адресу 03 относительно 0; 0+03=03. Sw $s1, 03 ($s0) # сохранение в память по адресу 0+03=03 из регистра s1.
1.4. Адресация относительно счетчика команд.
Инструкции условного перехода, или ветвления, используют адресацию относительно счетчика команд для определения нового значения счетчика команд в том случае, если нужно осуществить переход. Смещение со своим знаком прибавляется к счетчику команд (PC) для определения нового значения счетчика команд PC, поэтому тот адрес, куда будет осуществлен переход, называют адресом относительно счетчика команд.
1.5. Псевдо прямая адресация.
При прямой адресации целевой адрес перехода обычно задается внутри инструкции.
Инструкций j и jal. У этих инструкций адресное поле состоит из 26 b, т.к. остальные 6 b используются для операционного кода инструкции. Поэтому адрес перехода 32 b не возможно задать внутри инструкции и он вычисляется специальным алгоритмом.
1.4. Адресация относительно счетчика команд - Вычисление целевого адреса ветвления.
Коднаязыкеасс мблера |
MIPS Целевой адрес ветвления - это адрес инструкции, которая |
|
0xA4 beq $t0, $0, else |
# PC+4 |
будет выполнена следующей, если случится ветвление. |
0xA8 addi $v0, $0, 1 |
У инструкции beq целевой адрес ветвления равен 0хВ4 – |
|
0xAC addi $sp, $sp, 8 |
|
это адрес инструкции с меткой else. 16-битный |
0xB0 jr $ra |
$a0, |
непосредственный операнд задаёт число инструкций между |
0xB4 else: addi $a0,−1 |
целевым адресом 0xB4 ветвления и инструкцией, находящейся |
|
0xB8 jal factorial |
|
сразу после инструкции перехода 0xA8 (т.е. относительно |
|
|
инструкции следующего адреса счетчика команд PC + 4). |
В данном случае 16-битный операнд равен 3, т.к. целевой адрес ветвления расположен через 3 инструкции после инструкции с адресом РС+4= 0хА4+4=0хА8. Должен отсчитать сколько операндов между инструкцией, следующей за переходом и меткой
Машинный код для инструкции beq
Непосредственный операнд равен 3 потому, что целевой адрес ветвления (0xB4)
расположен через 3 инструкции после инструкции следующей за переходом с
адресом (0xA8):
А 8 + 4 = A C + 4 = |
B 0 + 4 = В 4 |
Расчет целевого |
1010 1000 + 100= 1010 1100 + 100 = |
1011 0000 + 100 = 1011 0100 |
адреса ветвления |
1.4 АДРЕСАЦИЯ ОТНОСИТЕЛЬНО СЧЕТЧИКА КОМАНД (Вычислении целевого адреса, который находится раньше, чем сама команда ветвления)
0x40 |
loop: |
add $t1, $a0, $s0 |
|
0x44 |
|
lb $t1, 0($t1) |
|
0x48 |
|
add $t2, $a1, $s0 |
|
0x4C |
|
sb $t1, 0($t2) |
|
0x50 |
|
addi $s0, $s0, 1 |
|
0x54 |
|
bne $t1, $0, loop |
|
0x58 |
|
lw $s0, 0($sp) |
#PC+4 |
целевой код находится на 6 инструкций раньше, чем значение счетчика РС+4 = 0х58 относительно счетчика команд РС - инструкции ветвления
Инструкция ветвления
Целевой адрес инструкции ветвления равен 0x40 по метке loop: и находится на 6 инструкций
раньше, чем следующее значение счетчика команд PC+4 =0х54 +4=0x58 относительно инструкции ветвления bne $t1, $0, loop при значении счетчика РС= (0х54), поэтому непосредственный операнд в
этом случае равен –6 (От адреса 0х58 до адреса 0х40 находятся 6 инструкций).
1 5 2 0 F F F A
Пояснения: где imm = 1111 1111 1111 1010 –дополнительный код числа -6
Код числа 6 = 0110, инверсия – 1001, дополнительный код 1001+1=1010 остальную часть добавляется единицами, получаем искомое 16 битное число в двоичном коде:
1111 1111 1111 10102 Что соответствуют адресу ветвления = 0х 1520FFFA
1.5. Псевдо прямая адресация (вычисление адреса перехода).
При прямой адресации адрес перехода задаётся внутри инструкции. Инструкции безусловного перехода j и jal в идеале могли бы использовать прямую адресацию для определения 32-битного целевого адреса перехода, указывающего адрес инструкции, которая будет выполнена следующей.
Однако, в формате инструкций типа J и jal нет достаточного количества бит для того,
чтобы задать полный 32-битный адрес перехода потому , что:
код инструкции перехода
|
|
26 бит адреса перехода |
6 старших бит |
|
|
инструкции занимает код |
|
берутся из поля addr |
операции |
|
инструкции. |
|
|
|
|
opcode 6b |
Adr 26b |
|
Вычисление |
|
|
|
|
|
|
|
адреса |
4b=PC+4 |
Adr 26b |
2b=0 |
перехода |
(31:28) |
(27:2) |
(1:0) |
|
два младших бита адреса перехода (J 1 : 0 ) всегда должны быть равны нулю
Четыре старших бита адреса перехода (J31:28) берутся из четырёх старших бит значения счетчика команд (кода операции), далее используются 26 бит адреса команды и последние 2 бита заполняются нулями. Итого: 32 бита команды.
Такой способ адресации называется псевдо прямым
Пример кода инструкция jal, с использованием псевдо прямой адресации.
Код на языке ассемблера MIPS:
0x0040005C jal sum ... Инструкция перехода на метку sum c адресом 0х004000А0
…………………………………………….
0x004000A0 sum: add $v0, $a0, $a1
Целевой адрес безусловного перехода этой инструкции равен 0x004000A0.
Код инструкции перехода состоит из операционного кода – 6 bit и кода адреса – 26 bit
Инструкция op adr
Jal sum |
|
3 |
0x 0100028 |
|
|
Машинный код команды |
6 bit |
26 bit |
|||
0х0C100028 |
|
|
|
|
|
000011 |
00 0001 0000 0000 0000 0010 1000 |
||||
|
|||||
|
|
|
|
|
0 C 1 0 0 0 2 8
Вычисление целевого адреса перехода:
32 битный код адреса инструкции 0000 0000 0100 0000 0000 0000 1010 0000
Исходный адрес из команды перехода
Целевой адрес перехода Jal:
Четыре старших бита адреса перехода берутся из четырёх старших бит значения PC + 4.
0000 0000 0100 0000 0000 0000 1010 0000 (0x004000A0)
Инструкция безусловного перехода по |
|
|
Два младших бита |
||
регистру (jr) не является инструкцией типа J. |
||
Она является инструкцией типа R и |
всегда должны быть |
|
выполняет переход по 32-битному адресу, |
равны нулю. |
|
находящемуся в регистре rs |
||
|
|
2.Карта оперативной памяти
Так как архитектура MIPS использует 32-битные адреса, то размер адресного пространства (Segment) определяется, как 232 = 4 Гбайта. Адреса слов кратны 4 и располагаются в промежутке от 0x00000000 до 0xFFFFFFFC.
Сегмент кода программы (англ.: Text) содержит машинные команды исполняемой программы. Его размер 256 Мбайт. Четыре старших бита адреса в сегменте кода всегда равны нулю, что позволяет использовать инструкцию J для перехода по любому адресу в программе. Адреса text от 0х00400000 до 0х0FFFFFFC.
Сегмент глобальных данных (англ.: Global Data ) содержит глобальные переменные, которые, в отличие от локальных переменных, находятся в области видимости всех функций программы. Глобальные переменные инициализируются при загрузке программы, но до начала ее выполнения. В программе на языке Си эти переменные объявляются вне функции main и доступны для всех функций. Размер этого сегмента 64 Кбайт Доступ к глобальным переменным осуществляется при помощи глобального указателя ($gp), который инициализируется значением адреса 0x10008000. В отличие от указателя стека ($sp), $gp не меняется во время выполнения программы. Любая глобальная переменная доступна при помощи16-битного положительного или отрицательного смещения относительно $gp. Для доступа к глобальным переменным можно использовать режим базовой адресации с константными смещениями.
3.Трансляция и запуск программы
Объектный Файл в машинных кодах
Программный код языка высокого уровня Компиляция
Код ассемблера Ассемблирование
Файлы библиотек
Компоновщик
Лицензирование
Загрузчик
Память
Этапы трансляции программы в машинный язык, написанной на языке высокого уровня. Высокоуровневый код компилируется в код на языке ассемблера.
Код ассемблера переводится в машинный код и сохраняется в виде объектного файла.
Компоновщик, называемый редактором связей или линкером (англ.: linker- связь), объединяет
полученный объектный код с объектным кодом библиотек и других файлов, в результате получается готовая к исполнению программа.
На практике, большинство компиляторных пакетов выполняют все три шага:
компиляцию, ассемблирование и компоновку.
Загрузчик загружает программу в память и запускает ее.
Этап1 . КОМПИЛЯЦИЯ ПРОГРАММЫ: программа сложение глобальных переменных f и g с использованием Стека оперативной памяти при выполнении двух функций, вложенных друг в друга.
.data |
директива ассемблера: начало сегмента данных |
||||
f: |
|
3 глобальные переменные: f+g=y |
|||
g: |
|
||||
y: |
|
|
|
|
|
.text |
директива ассемблера: начало текста программы |
||||
main: |
# вызов главной функция программы main |
||||
addi $sp, $sp, −4 |
|
пространства на Стеке вниз на 4b |
|||
# создание |
|||||
sw |
$ra, 0($sp) |
# сохранение адреса возвращаемого регистра $ra на стеке |
|||
addi $a0, $0, 2 |
# в аргумент а0 добавляем 2 $a0 = 2 |
||||
sw |
$a0, f |
# сохраняем а0 в глобальной переменной f = 2 |
|||
addi $a1, $0, 3 |
# в аргумент а1 добавляем 3 $a1 = 3 |
||||
sw |
$a1, g |
# сохраняем а1 в глобальной переменной g = 3 |
|||
jal sum |
# вызов функции sum с запоминанием регистра возврата |
||||
sw |
$v0, y |
# возврат |
|
|
|
и сохранение sum(f, g) глобальных переменных в глобальной переменной у=5 |
|||||
Iw |
$ra, 0($sp) |
# запись в $ra адреса указателя стека (возврат $ra из Стека) |
|||
addi $sp, $sp, 4 |
# возврат указателя Стека в исходное положение вверх на 4b (в начало Стека) |
||||
jr |
$ra |
# переход по регистру к регистру $ra |
sum: |
add $v0, $a0, $a1# исполнение функции sum =а0+а1=$sv,cохранение результата в $v0, возврат к функции jal |
jr $ra |
# возврат к главной функции по адресу, указаному в регистре $ra |
В примере кода показана простая программа, содержащая три глобальные переменные f, g и y и две функции sum(f,g) и main. Первая функция main к которой возврат происходит по указанному адресу в регистре возврата $ra (красные стрелы). Вторая функция sum – функция с возвратом (синие стрелы) внутри первой функции. Ключевые слова .data и .text – это ассемблерные директивы, указывающие на начало сегментов данных и кода в памяти соответственно. Для обозначения глобальных переменных f, g и y используются метки. Места для их хранения будут определены ассемблером. На данный момент они остаются в коде в виде символов.