Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / 1CompArch.doc
Скачиваний:
36
Добавлен:
20.06.2014
Размер:
657.41 Кб
Скачать

Программирование эвм

Низкий и высокий уровни программирования

Выделяются два уровня программирования:

  • низкий — уровень команд процессора;

  • высокий — уровень алгоритмических действий решаемой задачи.

На низком уровне можно программировать в машинных кодах (на машинном языке, языке процессора) или на языке ассемблера. На высоком уровне используется язык программирования высокого уровня (ЯВУ). Одному оператору языка высокого уровня может соответствовать множество команд процессора. Одной команде ассемблера соответствует ровно одна команда процессора.

Интерпретатор, транслятор, компилятор и ассемблер

При программировании на каком-либо языке, отличном от машинного, неважно, высокого или низкого уровня, требуется специальная программа, которая переводит разрабатываемую программу с языка программирования на язык процессора, машинный язык. Существует два варианта перевода и исполнения разрабатываемой программы:

  • покомандно — когда очередная команда (оператор) переводится и сразу исполняется;

  • целиком — когда переводится вся программа в целом и только после этого исполняется.

Покомандная программа-переводчик называется интерпретатором. Пример интерпретатора — Basic. Программа-переводчик второго типа называется компилятором. Пример компилятора — С. Компилятор — это вид транслятора. Транслятор — это программа, которая переводит программу с одного языка программирования на другой. Компилятор — это программа, которая переводит программу с языка программирования высокого или низкого уровня на язык процессора. Файл с программой на языке программирования называется исходным, а с программой на языке процессора — объектным.

Ассемблер — это компилятор, который переводит программу с языка ассемблера на язык процессора. Часто ассемблером называют и сам язык ассемблера. Т. е. можно говорить: "Программировать на языке ассемблера" или "Программировать на ассемблере".

Интерпретация и компиляция могут сочетаться. Для этого вводится промежуточный уровень между языком программирования и языком процессора, который можно назвать языком виртуальной машины или среды исполнения. Программа с языка высокого уровня компилируется в промежуточный код, который затем исполняется в режиме интерпретации. Так происходит в среде .NET или JAVA.

Загрузчик

Итак, компилятор переводит программу на язык процессора. Но для выполнения ее нужно поместить в необходимую область памяти и передать ей управление. Это делает еще одна программа — загрузчик. В большинстве компьютеров используется специальная программа или комплекс программ — операционная система. Ее основное назначение состоит в запуске других программ на исполнение. В этом случае загрузчик входит в состав операционной системы. Для загрузки самой операционной системы используются два загрузчика: начальный, входящий в состав BIOS (Basic Input-Output System), базовой системы ввода-вывода, расположенной в ПЗУ компьютера, и расположенный на диске в загрузочном секторе. Теоретически их может быть сколько угодно. В операционных системах на основе NT загрузочный код содержится также в файле NTLDR (NT Load Direct Record).

Редактор, компоновщик и отладчик

Помимо компилятора и загрузчика для создания и запуска программы требуется еще множество программ, основными из которых являются:

  • текстовый редактор, с его помощью осуществляется ввод программы на языке программирования;

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

  • отладчик — программа, позволяющая исследовать разрабатываемую программу, прогнав ее покомандно или с заданными точками останова.

Соответствие между языком высокого уровня, языком ассемблера и языком процессора

Напишем простую программу сложения двух целых чисел на языке C:

int A = 1, B = 2, S;

void main()

{

S = A + B;

}

Тогда телу главной функции, которое состоит всего из одной строки с оператором присваивания и операцией сложения, будет соответствовать фрагмент кода на языке ассемблера и машинном языке, приведенный в табл.

Табл. Соответствие между фрагментами кода на различных языках

ЯВУ

Язык ассемблера

Язык процессора

1

S = A + B

mov AX, A

A1 AA 00

2

add AX, B

03 06 AC 00

3

mov S, AX

A3 90 02

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

Оператору присваивания переменной S результата сложения значений переменных A и B соответствуют три команды ассемблера и процессора. По команде mov AX, A процессор передает значение переменной A в аккумулятор. AX становится равным единице. Отметим, что размер целочисленных переменных в языке C — 16 бит. Таков же и размер регистра AX. На машинном языке команда mov AX, A представляется как трехбайтное число. Первый байт A1 — это код операции команды, который содержит информацию о действии (передать данные из памяти данных) и об операнде-приемнике, т. е. куда передать данные (регистр AX, аккумулятор). Код операции будет помещен процессором в регистр команд для дешифрации и выработки необходимых управляющих сигналов для выполнения команды. Второй и третий байты — это адрес переменной A. В языках программирования используются символическая запись действий и операндов, имена переменных и обозначения операторов и операций. Но процессор понимает только язык двоичных чисел. Поэтому вместо mov AX — A1, вместо имени переменной A — ее адрес, 00AA. В большинстве компьютеров принят т. н. обратный порядок хранения слов (little endian order). Если число занимает в памяти больше одного байта, то сначала, по младшему адресу, располагается младший байт, а затем последующие байты. Отметим, что адресация, при которой в команде располагается адрес операнда, называется прямой.

Почему адрес именно такой? Все три переменные, A, B и S, объявлены как глобальные. Они существуют на протяжении всего времени работы программы и доступны из любых ее частей. Такие переменные располагаются в памяти в отдельной области (сегменте) данных. Указанные адреса отсчитываются от начала этого сегмента и называются смещениями. Компилятор расположил эти переменные в сегменте данных так, что их смещения приняли именно такие конкретные значения.

Вторая команда прибавляет к аккумулятору значение переменной B и результат помещает в аккумулятор. Таким образом, в аккумуляторе оказывается сумма переменных A и B. Длина команды сложения — четыре байта. Первые два байта — 03 06 — код операции с уточнением способа адресации. Следующие два байта — адрес переменной B, 00AC. 00AC - 00AA = 2 — таким образом, переменные A и B располагаются в памяти одна за другой.

Третья команда передает результат сложения из аккумулятора в переменную S. Ее адрес — 0290. Компилятор расположил ее на некотором расстоянии от переменных A и B.

Структура программы на языке ассемблера

Полный текст программы на языке ассемблера, выполняющей сложение двух переменных и помещающей результат сложения в третью переменную, мог бы выглядеть так:

;sum.asm — программа, вычисляющая S=A+B

data segment ;объявление начала сегмента данных

a dw 01h ;объявление и инициализация переменной A

b dw 02h ;объявление и инициализация переменной B

s dw ? ;объявление переменной S

data ends ;объявление конца сегмента данных

code segment ;объявление начала сегмента команд (кода)

assume ds:data ;регистр DS будет указывать на сегмент data

begin: mov dx, data ;точка входа в прогамму, DX = data

mov ds, dx ;теперь DS указывает на сегмент data

mov ax, a ;AX = A = 1

add ax, b ;AX = AX + B = A + B = 1+ 2 = 3

mov s, ax ;S = AX = 3

mov ax, 4c00h ;функция завершения программы MS-DOS c

Соседние файлы в папке Лекции