Россия и Беларусь начали и продолжают войну против народа Украины!

Ассемблер. Процедуры

  Светлана Деменева  | 

  Обновл. 16 Сен 2021  | 

 15382

 ǀ   2 

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

Процедуры в Ассемблере

Ниже приведен синтаксис определения процедуры:

имя_процедуры:
    тело_процедуры
    ...
    ret

Процедура вызывается из другой функции с помощью инструкции CALL, которая содержит имя вызываемой процедуры в качестве аргумента: 

CALL имя_процедуры

Вызываемая процедура возвращает управление вызывающей процедуре с помощью инструкции RET.

Например, давайте напишем очень простую процедуру с именем sum, которая будет складывать переменные, хранящиеся в регистрах ECX и EDX, и возвращать сумму в регистр EAX:

Результат выполнения программы:

The sum is:
9

Стек как структура данных


Стек — это структура данных в памяти в виде массива, в котором эти данные могут храниться и удаляться из места, называемого «вершиной» стека. Данные, которые должны быть сохранены, «помещаются» в стек, а данные, которые должны быть извлечены — «выталкиваются» из стека. Стек — это структура данных типа LIFO (англ. «Last In, First Out» = «Последним пришёл, первым ушёл»), детально об этом читайте здесь.

Язык ассемблера предоставляет две инструкции для операций со стеком: PUSH и POP. Эти инструкции имеют следующий синтаксис:

PUSH    операнд
POP     адрес/регистр

Пространство памяти, зарезервированное в сегменте стека, используется для реализации стека, а именно — регистры SS и ESP (или SP). На вершину стека, которая указывает на последний добавленный элемент, указывает регистр SS:ESP, где регистр SS указывает на начало сегмента стека, а SP (или ESP) показывает смещение в сегменте стека.

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

Например, давайте напишем программу, которая будет выводить весь набор ASCII-символов:

Результат выполнения программы:

0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}
...
...

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (24 оценок, среднее: 4,17 из 5)
Загрузка...

Комментариев: 2

  1. somebox:

    Для чего в последнем примере мы помещаем 256 в ECX? Также не совсем понятен момент с работой display. Не должны ли мы после выполнения 10-й строки выходить из процедуры и возвращаться в блок _start, а там и вовсе выходить из программы?

    1. Владлен:

      Регистр ECX — это счётчик (counter). Каждый loop уменьшает его на единицу и делает переход, а как дойдет до нуля —Продолжит выполнение следующей инструкции. Соответсвенно цикл выполнится 256 раз. Столько символов в одном байте (от 0 до 255).

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

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *