Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

1 курс 2 семестр / лекции / Лекция 5 Адресация и опер память — копия

.pdf
Скачиваний:
9
Добавлен:
07.06.2023
Размер:
1.02 Mб
Скачать

Лекция 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 Что соответствуют адресу ветвления = 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

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

 

 

Сегмент динамических данных (англ.: Dynamic Data) содержит Стек (Stack) и
Кучу (Heap). В момент запуска программы этот сегмент не содержит данных
– они динамически выделяются и освобождаются в нем в процессе выполнения программы. Сегмент динамических данных – это самый большой сегмент памяти, используемый программой; его размер составляет почти 2 Гбайт.
Стек используется для сохранения и восстановления регистров,
используемых функциями, а также хранения локальных переменных, таких как массивы. Стек растет вниз от верхней границы сегмента динамических данных (0x7FFFFFFC=$sp – указатель стека), а доступ к кадрам стека осуществляется в режиме очереди LIFO («последним пришел – первым ушел»).
Куча хранит блоки памяти выделяемые программе во время работы. Данные в Куче можно использовать и выбрасывать в произвольном порядке. Куча растет вверх от нижней границы сегмента динамических данных (0х10010000). Если стек и куча прорастут друг в друга, данные программы могут быть повреждены. Функция выделения памяти контролирует эту ситуацию и вырабатывает ошибку нехватки памяти (англ.: out-off memory error),если свободной памяти недостаточно.
Резервный сегмент (англ. Reserved) используется только операционной системой и не может использоваться непосредственно программой. Часть зарезервированной памяти используется для прерываний и для отображения устройств ввода-вывода в адресное пространство.

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 используются метки. Места для их хранения будут определены ассемблером. На данный момент они остаются в коде в виде символов.