Как стать программистом Как устроен компьютер. Что такое программа. Как написать свою программу. И многое другое узнаете вы из этой книги. Получить бесплатно! |
Функции и процедуры на ассемблере
Главная / Ассемблер / Ассемблер и языки высокого уровня /
Лучшие книги по Ассемблеру
Сделал подборку не новых, но проверенных книг по программированию на языке ассемблера. Если вы также как и я любите погружаться на низкий уровень, в те закоулки мира программирования, куда не всем путь открыт, то посмотрите. Возможно, что-то вам понравится. Подробнее... |
В общих чертах о том, как использовать вставки на ассемблере в Delphi, Lazarus и FreePascal я рассказывал здесь. Сегодня расскажу ещё об одном способе - об ассемблерных процедурах и функциях.
Для того, чтобы создать чисто ассемблерную подпрограмму, которую затем можно использовать и в
ассемблерных вставках, в заголовок функции или процедуры надо добавить модификатор assembler
. Например:
{$ASMMODE INTEL} var z : WORD; // Ассемблерная процедура procedure AsmProc(x, y : WORD); assembler; asm MOV AX, x ADD AX, y MOV z, AX end;
Поскольку в примерах используется синтаксис ИНТЕЛ, не забудьте установить соответствующий режим
(первая строка в примере). Здесь мы используем глобальную переменную z
для передачи результата из процедуры в программу. Но в ассемблерной процедуре могут быть и локальные переменные:
procedure AsmVars; assembler; var a, b : WORD; asm MOV a, 1 MOV b, 2 MOV AX, a ADD AX, b MOV z, AX end;
Компилятор резервирует место в стеке для локальных переменных, при этом он вставляет некоторые команды в программу.
Ассемблерная функция может возвращать результат. В случае с синтаксисом ИНТЕЛ для этого используется макрос
@Result
:
// Ассемблерная функция function SumXY(x, y : WORD) : WORD; assembler; asm MOV AX, x ADD AX, y MOV @Result, AX //Только для процессоров ИНТЕЛ end;
Пример использования описанных выше подпрограмм в программе:
WriteLn('X = ', 100, ', Y = ', 200); AsmProc(100, 200); WriteLn('X + Y = ', z); WriteLn('X + Y = ', SumXY(100, 200)); asm CALL AsmVars //Вызов ассемблерной процедуры в блоке asm end; WriteLn('1 + 2 = ', z);
Следующее мало кому пригодится, но, поскольку в документации об этом сказано, то и я расскажу.
Имя ассемблерной функции будет изменено компилятором. То есть метка для этой функции будет иметь
не такое имя, как указано в определении функции. Чтобы определить имя функции, которое можно
потом найти в ассемблерном коде (в файле с расширение .о
), надо использовать модификатор alias
:
// Использование алиаса (псевдонима) procedure AsmNOP; assembler; [alias:'ASM_NOP']; asm NOP end;
Допустим, имя исходного файла у нас asmtest.lpr
. Тогда компилятор FreePascal создаст файл
asmtest.o
. И в этом файле вы нигде не найдёте имя функции AsmNOP
.
То есть вы не найдёте метки, с которой начинается код этой функции. Но если вы зададите алиас
(в нашем примере ASM_NOP
), то этот алиас вы уже сможете найти в файле asmtest.o
:
Кроме того, есть ещё модификатор public
. Его надо использовать, чтобы сделать функцию доступной вне текущего модуля:
procedure AsmUnit; assembler; [public, alias: 'ASM_UNIT']; asm MOV AX, 10 MOV BX, 5 MUL BX end;
Честно говоря, не знаю, на что это влияет. В моих экспериментах получалось использовать ассемблерные
процедуры из других модулей без модификатора public
. Возможно, документация устарела и теперь это необязательно.
На этом пока всё. Об особенностях использования языка ассемблера ИНТЕЛ в Lazarus и FreePascal расскажу в другой раз.
Вступить в группу "Основы программирования"
Подписаться на канал в РУТУБ Подписаться на рассылки по программированию |
Первые шаги в программирование
Главный вопрос начинающего программиста – с чего начать? Вроде бы есть желание, но иногда «не знаешь, как начать думать, чтобы до такого додуматься». У человека, который никогда не имел дело с информационными технологиями, даже простые вопросы могут вызвать большие трудности и отнять много времени на решение. Подробнее... |