1 курс 2 семестр / лекции / Лекция 5 Адресация и опер память — копия
.pdfЭТАП 2. ТРАНСЛЯЦИЯ ПРОГРАММЫ.
Ассемблер транслирует код на языке ассемблера в объектный файл, содержащий код на
машинном языке.
При трансляции кода ассемблер делает два прохода. Во время первого прохода ассемблер
назначает адреса командам и находит все символы, такие как метки и имена глобальных переменных. После первого прохода ассемблера код выглядит следующим образом:
0x00400000 |
main: |
addi $sp, $sp, −4 |
|
0x00400004 |
|
sw |
$ra, 0($sp) |
0x00400008 |
|
addi $a0, $0, 2 |
|
0x0040000C |
|
sw |
$a0, f |
0x00400010 |
|
addi $a1, $0, 3 |
|
0x00400014 |
|
sw |
$a1, g |
0x00400018 |
|
jal sum |
|
0x0040001C |
|
sw |
$v0, y |
0x00400020 |
|
lw |
$ra, 0($sp) |
0x00400024 |
|
addi $sp, $sp, 4 |
|
0x00400028 |
sum: |
jr |
$ra |
0x0040002C |
add $v0, $a0, $a1 |
||
0x00400030 |
|
jr |
$ra |
Таблица символов
Символ Адрес
f0x10000000
g |
0x10000004 |
адреса области глобальных данных памяти |
|
y0x10000008
main |
0x00400000 |
адреса функций второго резерва |
sum |
0x0040001C |
|
Исполнение двух функций main и sum показано еще раз красными и синими стрелами
Имена и адреса символов хранятся в таблице символов. Адреса символов заполняются после первого прохода, когда адреса меток уже известны. Глобальным переменным
присваиваются адреса из сегмента глобальных данных, начиная с адреса 0x10000000. Во время второго прохода ассемблер генерирует машинный код.
Адреса глобальных переменных и меток берутся из таблицы символов
Исполняемый объектный файл
Заголовок |
Размер кода |
Размер данных |
|
||
|
Адрес |
Инструкция |
Сегмент кода
Адрес Данные
Сегмент данных
Объектный файл состоит из трех секций:
Заголовка (Executable file header), Сегмента кода
(Text segment) и Сегмента данных (Data segment).
Заголовок исполняемого файла содержит информацию о размерах сегмента кода программы (т.е. об объеме кода) и размерах сегмента данных
(т.е. о количестве глобально объявленных данных). Все размеры приведены в байтах.
Сегмент кода (Text segment). Команды в нем приведены в том же порядке, в котором они расположены в памяти. Рядом с машинным кодом показаны команды (в синем) в виде, удобном для восприятия. Исполняемый файл содержит только
машинные команды.
Сегмент данных задает адреса всех глобальных переменных. Доступ к глобальным переменным осуществляется при помощи базовой адресации относительно адреса, определяемого глобальным указателем $gp.
Например, команда sw $a0, 0x8000 ($gp) с базовой адресацией относительно глобальной переменной
0x8000 ($gp) присваивает значение 2 глобальной переменной f, которая размещена в памяти по адресу 0x10000000. При этом, смещение составляет
0x8000 – это 16-битное число со знаком, которое после знакового расширения до 32 битов прибавляется к базовому адресу, находящемуся в регистре глобальных переменных $gp. с адресом: 0x10000000.
Таким образом, $gp + 0x8000 = 0x10000000 + 0x00008000 = 0x10008000 – это и будет адрес переменной f.
Этап 4: Загрузка.
Операционная система загружает программу, считывая сегмент кода исполняемого файла с
устройства хранения данных (обычно это жесткий диск) в сегмент кода памяти (Text). Операционная система сначала присваивает регистру $gp значение 0x10008000, равное середине сегмента глобальных данных (рисунок Памяти), затем присваивает указателю стека регистру $sp
значение 0x7FFFFFFC, равное верхней границе сегмента стека динамических данных, после чего выполняет команду main по адресу 0x00400000 для перехода к началу программы сложения. На Рис.1 показана карта памяти в начале выполнения программы, а на рис.2. приеден исполняемый файл программы.
Сегмент динамических данных
Сегмент глобальных данных
Объектный код
программы
Сегмент Text
Рис.1. Карта памяти в начале выполнения программы |
Рис.2.Исполняемый файл |