Э. Таненбаум - Архитектура компьютера (1127755), страница 142
Текст из файла (страница 142)
Наконец, ассемблерная программа может работать только на компьютерах одного семейства, а программа, написанная на языке высокого уровня, потенциально может работать на разных машинах. Возможность переноса программного обеспечения с одной машины на другую очень важна для многих прикладных программ. Назначение ассемблера Работать с языком ассемблера непросто. Написание одной и той же программы на ассемблере занимает гораздо больше времени, чем на языке высокого уровня. Кроме того, очень много времени занимает отладка. Но зачем же тогда вообще писать программы на ассемблере? Есть две причины; производительность и доступ к аппаратуре.
Прежде всего, квалифицированный программист, пишущий на ассемблере, может составить гораздо меньшую по объему и гораздо более быстродействующую программу, чем программа, написанная на языке высокого уровня. Для некоторых программ быстродействие и объем имеют чрезвычайно важное значение. К этой категории относятся многие встроенные прикладные программы (напрнмер, в смарт-картах, сотовых телефонах, драйверах устройств) и процедуры В109. Следующая причина в том, что некоторым процедурам требуется полный доступ к аппаратному обеспечению, который обычно невозможно обеспечить средствами языков высокого уровня.
В эту категорию попадают обработчики прерываний и исключений операционных систем, а также контроллеры устройств встроенных систем, работаюгцих в режиме реального времени. Первая причина (достижение высокой производительности) является более важной, поэтому мы рассмотрим ее подробнее. В большинстве программ лишь небольшой процент всего кода сказывается на времени выполнения программы. Обычно 1 ' кода отвечает за 50 ' времени выполнения, а 10 о кода — за 90 о времени выполнения.
Предположим, что для написания программы на языке высокого уровня требуется 10 человеко-лет, а полученной программе нужно 100 секунд, чтобы выполнить 660 Глава 7. Уровень ассемблера некоторую типичную контрольную программу. (Контрольной называют тестовую программу, которая используется для сравнения компьютеров, компиляторов и т. п.) Написание всей программы на ассемблере может занять 50 человеко-лет.
Полученная в результате контрольная программа будет выполняться примерно ЗЗ секунды, поскольку хороший программист может оказаться в три раза умнее компилятора (хотя об этом можно спорить бесконечно). Ситуацию иллюстрирует табл. 7.1. Таблица 7.1. Сравнение программирования на ассемблере и языке высокого уровня Время программирования, Время выполнения челояеко-лет программы, с Язык ассемблера 30 33 Язык высокого уровня 10 Смешанный подход до подстройки 100 Критические 1О % Остальные 90 % Всего 10 10 100 Смешанный подход после подстройки Критические 10 % Остальные 90 % Всего 30 1О 40 Так как только крошечная часть программы отвечает за большую часть времени выполнения этой программы, возможен другой подход. Сначала программа пишется на языке высокого уровня.
Затем проводится ряд измерений, чтобы определить, какие части программы по большей части сказываются на времени выполнения. Для таких измерений обычно используется системный тактовый генератор. С его помощью можно узнать, сколько времени выполняется каждая процедура, сколько раз выполняется каждый цикл и т. п. Предположим, что 10 % программы отвечает за 90 % времени ее выполнения. Это значит, что из 100 секунд работы 90 секунд выполняется десятая часть программы, а 10 секунд — оставшиеся 90 %.
Эти 10 % программы можно усовершенствоватгч переписав на ассемблере. Этот процесс называется подстройкой (тпшпй). На подстройку основных процедур потребуется еще 5 человеко-лет, но время выполнения программы сократится с 90 до 30 секунд. Сравним этот смешанный подход, когда используются и ассемблер, и язык высокого уровня, с подходом, в котором применяется только язык ассемблера (см. табл. 7.1). При втором подходе программа работает примерно на 20 % быстрее (33 секунды против 40), но более чем за тройную цену (50 человеко-лет против 15). Более того, у смешанного подхода есть еще одно преимущество: гораздо проще переписать на ассемблер уже отлаженную процедуру, написанную на языке высокого уровня, чем писать эту процедуру на ассемблере чс нуля». Отметим, что, если бы написание программы занимало ровно 1 год, соотношение между Знакомство с ассемблером 561 смешанным подходом и подходом, при котором используется только язык ассемблера, составляло бы 4:1 в пользу смешанного подхода.
В то же время программисту, пишущему на языке высокого уровня, не нужно задумываться о перемещении отдельных битов, поэтому он может осмысливать задачу в целом, и иногда ему так удается построить программу, что он добивается реального повышения производительности. Такая ситуация обычно не характерна для программистов, пишущих на ассемблере, — как правило, они возятся с отдельными командами, пытаясь сэкономить несколько циклов. Как бы то ни было, существует по крайней мере 4 веские причины для изучения ассемблера.
Во-первых, желательно уметь писать программы на ассемблере, поскольку успех или неудача большого проекта иногда зависит от того, удастся или нет в несколько раз повысить быстродействие единственной, но важной процедуры. Во-вторых, обращение к ассемблеру может быть единственно возможным выходом в случае нехватки памяти. Смарт-карты, например, содержат центральный процессор, но лишь у некоторых из них есть хотя бы мегабайт памяти и уж совсем единицы имеют жесткий диск для разбиения на страницы.
Однако при таких ограниченных ресурсах они должны выполнять сложные вычисления. Процессоры, встроенные в электроприборы, часто имеют минимальный объем памяти, поскольку они должны быть достаточно дешевыми. Столь же незначительным объемом памяти обычно оснащаются различные электронные устройства, работающие на батарейках, поскольку им нужен компактный, но эффективный код.
В-третьих, компилятор должен либо на выходе производить программу, которая может использоваться ассемблером, либо самостоятельно выполнять ассемблирование. Таким образом, знание языка ассемблера существенно для понимания того, как работает компьютер. И вообще, кто-то ведь должен писать компилятор (и его ассемблер). Наконец, ассемблер дает прекрасное представление о реальной машине.
Для тех кто изучает архитектуру компьютеров, написание ассемблерного кода— единственный способ узнать, что собой представляет машина. Формат оператора а ассемблере Хотя структура ассемблерного оператора отражает структуру соответствующей машинной команды, языки ассемблера для разных машин и разных уровней во многом похожи, что позволяет говорить о языке ассемблера в целом. В листингах 7.1 — 7.3 показаны фрагменты программ на ассемблерах Реп11пш 4, Могого1а 660х0 и (Игга)ЯРАКС. Все эти программы выполняют вычисление формулы М = 1 +,). Во всех трех примерах операторы над пустой строкой выполняют вычисление, а операторы под пустой строкой резервируют память для переменных 1, 3 и М.
То есть последние операторы не являются символьными представлениями машинных команд. Для компьютеров семейства 1пте! существует несколько ассемблеров, которые отличаются друг от друга синтаксисим. В этой книге мы будем использовать язык ассемблера М1сгозо(г МАЯМ.
И хотя мы будем говорить о процессоре 562 Глава 7. Уровень ассемблера Репгшш 4, все сказанное применимо и к процессорам 386, 486, Репсшт н РепСшш Рго. Для процессора ВРАТ мы будем использовать ассемблер 8пп, а все сказанное применимо и к более ранним 32-разрядным версиям. В книге коды операций и регистры всегда обозначаются прописными буквами, причем не только для ассемблера Репгшш 4, как зто обычно принято, но и для ассемблера 8пп, где по соглашению буквы строчные. Листинг 7.1. Вычисление выражения 1>! = 1+ д на ассемблере Релбапп 4 ГОЙМОСЯ. МОХ ЕАХ. 1 : регистр ЕАХ = ! ЯОО ЕАХ.О : регистр ЕАХ = 1 + 3 МОХ И,ЕАХ ;И=1+3 00 00 00 Листинг 7.2. Вычисление выражения й! = ! + 3 на ассемблере Мо1ого!а 680хО ГОЙМОСА МОХЕ Е 1.00 : регистр 00 - 1 АОО 4 3,00 ; регистр 00 = 1 + 3 МОХЕ Е ОО,И : И=1 -3 ОСЕ 3 ОС! 4 ОСА 0 .ЫОЙО 3 ЫОЙО 4 .НОНО 0 Ассемблерные операторы состоят из четырех полей: метки, операции, операндов и комментариев.
Метки служат символическими именами для адресов памяти. Они позволяют переходить к командам и данным, позволяя по символическому имени получить доступ к тому месту, где хранятся команды и данные. Если оператор снабжен меткой, то зта метка обычно располагается в начале строки. В каждом из трех примеров есть метки: РОКМША, 1, 1 и )чт. Отметим, что в ассемблере ВРАТ после каждой метки нужно ставить двоеточие, а в ассемблере Могого1а — нет. В ассемблере компьютеров 1пге! двоеточие ставится только Листинг 7.3. ГОЙМОСА: 5ЕТН1 ЕО 5ЕТН1 ЕО ИОР АОО 5ЕТН1 5Т резервирование 4 байт и их инициализация значением 3 резервирование 4 байт и их инициализация значением 4 резервирование 4 байт и их инициализация значениеи 0 резервирование 4 байт и их инициализация значениеи 3 резервирование 4 байт и их инициализация значвниеи 4 резервирование 4 байт и их инициализация значениеи 0 Вычисление выражения й) =! + 3 на ассемблере ВРАВС ЖН!! 1),Жй1 ! й1 = старшие биты адреса 1 ЕЖЙ!чЖЕО!1)).ЖЙ1 ! Й1 = 1 ЖН1!3).Жй2 ! Й2 = старшие биты адреса 3 ЕЖЙ2чЖЕОГО)1,ЖЙ2 ! Й2 - 3 ! ожидаеи получения 3 из памяти Жй1.ЖЙ2.ЖЙ2 ! Й2 = Й1 ч й2 ЖН1(И) .