Глава 8. Низкоуровневые возможности Паскаля
Язык Ассемблер
Специфика системных программ, ориентированных на непосредственное взаимодействие с физическими устройствами компьютера, а так же необходимость доступа ко всем его аппаратным возможностям, часто не позволяют создавать элементы программ средствами языков высокого уровня. Более того, исполняемый код, порождаемый компиляторами, менее эффективен, чем код, созданный вручную. Поэтому повышенные требования к быстродействию и объему программ вызывают необходимость использования машинных команд или языка ассемблера.
Ассемблер (assembler, assembly language – монтаж, сборка) – язык программирования, понятия которого отражают архитектуру ЭВМ. Обеспечивает доступ к регистрам, указание методов адресации и описание операций в терминах команд конкретного процессора. Ассемблер, содержащий средства более высокого уровня: встроенные и определяемые макрокоманды, соответствующие нескольким машинным командам, автоматический выбор команды в зависимости от типов операндов, средства описания структур данных и т.д., является макроассемблером.
Язык ассемблера используется при:
1. Создании драйверов низшего уровня и некоторых других программ, требующих прямого доступа к потенциальным возможностям компьютера.
2. Достижении наибольшей эффективности использования вычислительных ресурсов при вычислениях с большим количеством вложенных циклов. Самые внутренние циклы часто программируются на языке ассемблера.
3. Решении задач в реальном масштабе времени, то есть управляющих программ, которые требуют быстрой реакции вычислительной системы на внешние воздействия, и процессы, строго привязанные к определенным моментам времени. Более того, управляющие однокристальные ЭВМ обычно имеют маленький объем памяти.
4. Для управляющих ЭВМ набор языков программирования очень ограничен. Обычно это ассемблер и Си, причем последний часто отсутствует.
Изучение языка ассемблера дает понимание организации вычислительных процессов в процессоре, принципов его работы и позволяет создавать оптимальные программы и на языках высокого уровня.
Язык Турбо Паскаль допускает три основных вида доступа ко всем аппаратным возможностям ЭВМ:
1. Можно запрограммировать подпрограммы вне среды Паскаль на языке ассемблера или любом другом языке программирования и подключить полученный после ассемблирования или трансляции объектный модуль к Паскаль-программе.
2. Начиная с шестой версии в Паскале появились средства включения в текст программ фрагментов на языке ассемблера. Эти средства называются «встроенный ассемблер».
3. Можно непосредственно включать в текст программы фрагменты, написанные в машинном коде. Эти средства оставлены для совместимости с предыдущими версиями Турбо Паскаля и сейчас практически не используются и здесь не рассматриваются.
После трансляции с большинства языков программирования получается промежуточный объектный файл (OBJ-файл). Кроме непосредственно кодов он содержит некоторую дополнительную информацию.
Для подключения внешних подпрограмм в Паскале используется директива external, следующая за заголовком подпрограммы. Кроме этого, где-либо в тексте программы надо задать директиву компилятора $L, аргументом которой является имя OBJ-файла, содержащего код подключаемой подпрограммы, например:
Procedure SRoots(A,B,C:real); external;
Procedure CRoots(B,C,D.F:real); external;
...
{$L ROOTS.OBJ}
Для обеспечения корректности такого подключения необходимо соблюдать определенные межъязыковые соглашения о связях, принятые в системе Турбо Паскаль.
Средства встроенного ассемблера позволяют подключать ассемблерный текст непосредственно в Паскаль-программы, что гораздо удобнее и гибче, чем техника подключения независимо разработанных ассемблерных программ с помощью аппарата внешних подпрограмм.
Встроенный ассемблер реализует подмножество языка ассемблера, совместимого с языками Turbo Assembler фирмы Borland (TASM) и макроассемблера фирмы Microsoft (MASM). Хотя некоторые возможности по описанию структур не реализованы, но они во многом соответствуют описаниям Паскаль-объектов – констант, переменных, подпрограмм.
Средства, образующие встроенный ассемблер, организованы в виде двух конструкций: ассемблерные операторы (asm-операторы) и ассемблерные подпрограммы.
Структура asm-оператора:
asm
<команды (операторы) ассемблера>
end
Например:
asm
mov ah, 12 {работа с клавиатурой}
{информация о статусе смены регистра}
int 16h
mov OsnFlag,al
mov DopFlag,ah
end;
Обычно комментарии на ассемблере следуют за точкой с запятой. Но в asm-операторах используются ограничители, принятые для Паскаля: { } и (* *). Точкой с запятой могут разделяться команды ассемблера, но обычно используется общепринятый разделитель – переход на новую строку.
Поэтому возможна следующая запись:
asm
mov ax,Left; xchg ax,Right; mov Left,ax;
end;
Синтаксис команды:
[метка:][префикс] инструкция [операнд[,операнд]]
Инструкцией является мнемоническое обозначение действия, выполняемого командой.
Особенности использования asm-операторов.
1. Использование регистров. В связи с тем, что Паскаль использует некоторые регистры в своих целях, не допускается изменять содержимое регистров BP, SP, SS и DS.
2. Метки. Образование меток такое же, как и в Паскале. Они могут быть глобальными или локальными в asm-операторе. Но в последнем случае они не описываются и должны начинаться с символа «@».
3. Коды инструкций. Поддерживаются только все коды инструкций процессора i8086. Для использования расширения этих кодов для процессора i80286 и арифметических сопроцессоров необходимо использовать специальные директивы компилятора.
4. Зарезервированные слова. Для совместимости с ассемблером используется 41 зарезервированное слово, имеющее область действия только в asm-операторах. Эти слова имеют приоритет над именами пользователя, например:
Var Ch:char;
...
asm
mov Ch,1
end;
Здесь единица загружается в регистр процессора Ch, а не в ячейку памяти с именем Ch. Для указания описанного имени, совпадающего с зарезервированным словом, надо использовать перед именем символ «&»:
asm
mov &Ch,1
end;
5. Выражения. Использование выражений существенно отличается в Паскале и ассемблере. В Паскале упоминание переменной понимается как ее содержимое, а в asm-операторах обозначает адрес или константу. Поэтому оператор для х,
asm
mov AX,x+4
end;
описанного как переменная, не помещает значение х+4 в АХ, а загружает в регистр значение слова, хранящегося по адресу, на 4 байта большему х. Для увеличения х на 4 выполняются действия:
asm
mov AX,x
add AX,4
end;
Но записывать константы возможно следующим образом:
Const x=10;
y=20;
Var z:integer;
...
asm
mov z,x+y
end;
6. Есть 3 специальных переменных, одна из которых, @Result, обозначает переменную с результатом функции. Например, функция
Function Sum(x,y:integer):integer;
Begin
Sum:=x+y;
end;
эквивалентна
Function Sum(x,y:integer):integer;
Begin
asm
mov ax,x
add ax,y
mov @Result,ax
end;
end;
Для чисто ассемблерных подпрограмм может использоваться директива assembler. Это позволяет записывать подпрограммы полностью на языке ассемблера, с отсутствием операторных скобок и единственным asm-оператором:
Function LongMul(x,y:integer):longint; assembler;
asm
mov ax,x
imul y
end;
Использование @Result здесь не допускается, так как компилятор не образует переменную для результата функции. Обмен данными производится через регистры.
Дата добавления: 2016-06-29; просмотров: 1559;