Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТЯП-Лекция 01.docx
Скачиваний:
29
Добавлен:
11.06.2015
Размер:
3.67 Mб
Скачать

1.7. Машинный код

Машинный кодилимашинный язык– это язык, на котором записываются программы для данной машины или данного семейства машин. Этот код определяется набором кодов операций и форматом команд процессора, типом адресации ячеек, форматом представления данных в памяти и пр.

Для примера рассмотрим программу, которая выводит на консоль текст «Hello,world!», для процессора архитектуры x86 фирмыIntelc16-разрядной адресацией. В этой архитектуре адресуемой ячейкой памяти является каждый 8‑разрядный байт. Поле КОП команды занимает первый байт (т.е. допускается не более 28= 256 различных команд), поле адреса – 2 байта (т.е. можно адресовать 216 байтов = 65536 байтов = 64 КБ – длинный адрес) или 1 байт (можно адресовать только 256 байт – короткий адрес).

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

10111011

00010001

00000001

Для удобства чтения программ программисты записывают их в шестнадцатеричном(16-ричном) коде, заменяя каждую четвёрку битов одной 16-ричной цифрой (всего этих цифр 16), как показано в следующей таблице:

16-ричная цифра

Двоичное число

Десятичное число

0

0000

0

1

0001

1

2

0010

2

3

0011

3

4

0100

4

5

0101

5

6

0110

6

7

0111

7

8

1000

8

9

1001

9

A

1010

10

B

1011

11

C

1100

12

D

1101

13

E

1110

14

F

1111

15

10

10000

16

В любой системе счисления число, следующее за последней цифрой, равно 10, т.е. изображается двумя цифрами (см. в таблице 102, 1010и 1016).

Таким образом, эта команда в 16-ричной системе имеет вид ВВ 11 01. Байты 11 01 образуют здесь двухбайтовое поле адреса. Адрес, указанный в этом поле, – 011116, а не 110116. Чтобы записать правильный адрес, нужно поменять местами байты адресного поля! В десятичной системе этот адрес равен 273.

Вся программа в 16-ричном коде выглядит следующим образом (за программой последует её комментарий):

Адрес первого байта

Команды и данные25

1

25610

010016

BB 11 01

2

25910

010316

B9 0D 00

3

26210

010616

B4 0E

4

26410

010816

8A 07

5

26610

010А16

CD 10

6

26710

010B16

43

7

26910

010D16

E2 F9

8

27110

010F16

CD 20

9

27310

011116

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21

Программа размещена, начиная с ячейки с адресом 010016, и состоит из 8 команд, занимающих первые 17 байтов. После команд в неё включена выдаваемая строка текста «Hello,world!» – 13 символов (включая пробел). Каждый символ представлен своим 8‑разряднымASCII-кодом (см. любую таблицу символов). Вся строка занимает 1310=D16байтов:

Символы

H

e

l

l

o

,

w

o

r

l

d

!

Их коды

48

65

6C

6C

6F

2C

20

57

6F

72

6C

64

21

Таким образом, вся программа с данными занимает 30 байтов.

Команды с номерами 4 – 7 (выделены жирным шрифтом) повторяются столько раз, сколько символов в выводимой строке (13 раз). Это – цикл.

Комментарии к программе

В программе для передачи данных используются регистры: 8-разряд­ные – AL,AH(это байты 16-разрядного регистра АХ), 16‑разрядные –BX,CX. РегистрыCXиIP(адрес следующей команды) используются для организации цикла. Команды «знают», какие регистры они используют.

Вывод символа на консоль осуществляется операционной системой (BIOS) с помощью прерывания с номером 1016. Останов программы (возврат управления операционной системеMSDOSпосле завершения программы) осуществляется с помощью прерывания 2016. Команда останова необходима, иначе процессор начнёт следующий байт (4816– символ «Н») рассматривать как код операции, и это может привести к тяжёлым последствиям.

Адрес

Команды и данные

Комментарии

010016

BB 11 01

Поместить в BX адрес строки (байт с символом «Н» становится текущим)

010316

B9 0D 00

Поместить в CX длину строки (000D)

010616

B4 0E

Поместить в AH номер функции 0E16 прерывания 1016

010816

8A 07

Поместить в AL значение ячейки памяти, адрес которой находится в BX (т.е. текущий символ)

010А16

CD 10

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

010B16

43

Увеличить значение ВХ на 1 (сделать текущим следующий байт)

010D16

E2 F9

Если CX≠0, то уменьшить CX на 1 и увеличить IP (равный 010F) на F9 (равносильно уменьшению на 7, т.к. F9 – дополнительный код числа -7), т.е. перейти по адресу 010816 – на начало цикла

010F16

CD 20

Вызвать прерывание 2016: завершить программу

011116

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21

«Hello, world!»

Этот пример показывает, насколько сложно писать, читать (понимать) и отлаживать программу в машинном коде. Производительность программиста, программирующего в цифровом машинном коде, – всего несколько команд в день. В первых ЭВМ архитектура процессоров была гораздо проще, но пользоваться самим компьютером было значительно сложнее. Но именно такие языки позволяют максимально использовать возможности конкретной машинной архитектуры при создании максимально эффективных программ.

Поэтому уже в начале 1950-х годов стали появляться языки программирования, позволявшие записывать машинные команды и данные не в цифровом виде, в символическом, используя мнемонические имена команд, регистров, ячеек памяти. Эти языки называют языками символического кодирования.Для них создавались программы-трансляторы, преобразующие команды из символической записи в цифровую. Эти трансляторы, а вместе с ними и языки символического кодирования, назывались сначалаавтокодами, а позже ­ассемблерами(по-русски – «сборщиками»). Появление таких языков и трансляторов стало возможным лишь на машинах с архитектурой фон Неймана благодаря принципу хранимой программы (они и были созданы для первых таких машин26).

Приведём код той же программы на языке ассемблера:

mov bx, HW ; move - переместить

mov cx, 000Dh

mov ah, 0Eh

L: mov al, [bx]

int 10h ; interruption - прерывание

inc bx ; increment – увеличить на 1

loop L ; loop - цикл

int 20h

HW: db 'Hello, World!'

Кроме расшифровки смысла команд, здесь происходит автоматическое определение адресов команд и данных с помощью меток (LиHW). В целом, использование языков символического кодирования увеличило производительность программистов на порядок, сохраняя возможность использования всех особенностей архитектуры вычислительной системы. Таким образом, языки символического кодирования и программы-трансляторы автокоды и ассемблеры стали первым шагомавтоматизации программирования– одной из важнейших составляющих технологии программирования.

Однако, языки ассемблера и написанные на них программы привязаны к конкретной архитектуре вычислительной системы и не годятся для других систем. Кроме того, производительность программистов на ассемблере слишком низкая для написания того объёма программного кода, который требуется в современных условиях. Для удовлетворения этой потребности разрабатываются языки программирования высокого и сверхвысокого уровня – следующие шаги автоматизации программирования. На таких языках предыдущая программа превращается в один простой оператор:

write('Hello, World!')

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]