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

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

.pdf
Скачиваний:
18
Добавлен:
27.12.2022
Размер:
978.85 Кб
Скачать

Лекция 6. Адресация и оперативная память процессора.

Вопросы:

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 используют именно такой режим адресации.

1.2. Непосредственная адресация.

При непосредственной адресации в качестве операндов наряду с регистрами используют 16-битные константы (непосредственные операнды). Этот режим адресации используют некоторые инструкции типа I, такие как сложение с константой (addi) и загрузка константы в старшие 16 бит регистра (lwi).

1.3.Базовая адресация.

Инструкции для доступа в память, такие как загрузка слова (lw) и сохранение слова (sw), используют базовую адресацию. Эффективный адрес операнда в памяти

вычисляется путем сложения базового адреса в регистре rs и 16-битного смещения с расширенным знаком, являющегося непосредственным операндом.

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хА8)

Машинный код для инструкции beq

Непосредственный операнд равен 3 потому, что целевой адрес ветвления (0xB4)

расположен через 3 инструкции после инструкции с адресом (0xA8).

A 8 + 4 = A C + 4 =

B 0 + 4 = В 4

Получение целевого

1010 1000 + 100= 1010 1100 + 100 =

1011 0000 + 100 = 1011 0100

адреса ветвления

АДРЕСАЦИЯ ОТНОСИТЕЛЬНО СЧЕТЧИКА КОМАНД

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

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

целевой код находится на 6 инструкций раньше, чем значение счетчика РС+4 = 0х58 относительно счетчика команд РС - инструкции ветвления

0x54

bne $t1, $0, loop

 

0x58

lw $s0, 0($sp)

#PC+4

Целевой адрес инструкции ветвления равен 0x40 по метке loop: и находится на 6

инструкций раньше, чем следующее значение счетчика команд PC+4 =(0x58) относительно инструкции ветвления bne $t1, $0, loop при значении счетчика РС= (0х54),

поэтому непосредственный операнд в этом случае равен –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 ) всегда должны быть равны нулю

Четыре старших бита адреса перехода (J 3 1 : 2 8 ) берутся из четырёх старших бит значения счетчика команд, далее используются 26 бит адреса команды и последние 2 бита заполняются нулями. Итого: 32 b.

Такой способ адресации называется псевдо прямым

Пример кода инструкция jal, с использованием псевдо прямой адресации.

Код на языке ассемблера MIPS:

0x0040005C jal sum ... Инструкция перехода на метку sum c адресом 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 (0x 0100028)

Исходный адрес из команды перехода

Целевой адрес перехода 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 для перехода по любому адресу в программе.

Сегмент глобальных данных (англ.: Global Data ) содержит глобальные переменные, которые, в отличие от локальных переменных, находятся в области видимости всех функций программы. Глобальные переменные инициализируются при загрузке программы, но до начала ее выполнения. В программе на языке Си эти переменные объявляются вне функции main и доступны для всех функций. Размер этого сегмента 64 Кбайт Доступ к глобальным переменным осуществляется при помощи глобального указателя ($gp), который инициализируется значением 0x10008000. В отличие от указателя стека ($sp), $gp не меняется во время выполнения программы. Любая глобальная переменная доступна при помощи16-битного положительного или отрицательного смещения относительно $gp. Для доступа к глобальным переменным можно использовать режим базовой адресации с константными смещениями.

Сегмент динамических данных (англ.: Dynamic Data) содержит стек (Stack) и

кучу (Heap). В момент запуска программы этот сегмент не содержит данных

– они динамически выделяются и освобождаются в нем в процессе выполнения программы. Сегмент динамических данных – это самый большой сегмент памяти, используемый программой; его размер составляет почти 2 Гбайт.

Стек используется для сохранения и восстановления регистров,

используемых функциями, а также хранения локальных переменных, таких как массивы. Стек растет вниз от верхней границы сегмента динамических данных (0x7FFFFFFC=$sp – указатель стека), а доступ к кадрам стека осуществляется в режиме очереди LIFO («последним пришел – первым ушел»).

Куча хранит блоки памяти выделяемые программе во время работы. Данные в куче можно использовать и выбрасывать в произвольном порядке. Куча растет вверх от нижней границы сегмента динамических данных (0х10010000). Если стек и куча прорастут друг в друга, данные программы могут быть повреждены. Функция выделения памяти контролирует эту ситуацию и вырабатывает ошибку нехватки памяти (англ.: out-off memory error),если свободной памяти недостаточно.

Резервный сегмент (англ. Reserved) используется только операционной системой и не может использоваться непосредственно программой. Часть зарезервированной памяти используется для прерываний и для отображения устройств ввода-вывода в адресное пространство.

3.Трансляция и запуск программы

Объектный Файл в машинных кодах

Программный код языка высокого уровня Компиляция

Код ассемблера Ассемблирование

Файлы библиотек

Компоновщик

Лицензирование

Загрузчик

Память

Этапы трансляции программы в машинный язык, написанной на языке высокого уровня.

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

Компоновщик, называемый редактором связей или линкером (англ.: linkerсвязь), объединяет

полученный объектный код с объектным кодом библиотек и других файлов, в результате получается готовая к исполнению программа.

На практике, большинство компиляторных пакетов выполняют все три шага:

компиляцию, ассемблирование и компоновку.

Загрузчик загружает программу в память и запускает ее.

Этап1 . КОМПИЛЯЦИЯ ПРОГРАММЫ: программа сложение глобальных переменных f, g

.data

директива ассемблера

f:

 

 

 

g:

 

3

глобальные переменные

y:

 

 

 

.text

директива ассемблера

main:

функция main

addi $sp, $sp, −4

# создание пространства на стеке вниз на 4b

sw

$ra, 0($sp)

# сохранение возвращаемого регитсра $ra на стеке

addi $a0, $0, 2

# в $a0 = 2

sw

$a0, f

# f = 2 глобальная переменная

addi $a1, $0, 3

# в $a1 = 3

sw

$a1, g

# g = 3 глобальная переменная

jal sum

# вызов функции sum с запоминанием регистра возврата

sw

$v0, y

# сохранение y = sum(f, g) глобальная переменная

Iw

$ra, 0($sp)

# возврат $ra из стека

addi $sp, $sp, 4

# возврат указателя стека

jr

$ra

# возврат к операционной системе

sum:

add $v0, $a0, $a1 # исполнение функции sum и сохранение результата в $v0

jr $ra

# возврат к вызывающей функции

В примере кода показана простая программа, содержащая три глобальные переменные f, g и y и две функции sum(f, g) и main , а также ассемблерный код, сгенерированный типичным компилятором. Ключевые слова .data и .text – это ассемблерные директивы, указывающие на начало сегментов данных и кода в памяти соответственно. Для обозначения глобальных переменных f, g и y используются метки. Места для их хранения будут определены ассемблером.

На данный момент они остаются в коде в виде символов.