Ret ассемблер что это

19. Простые процедуры в ассемблер

Статья основана на материале xrnd с сайта asmworld (из учебного курса по программированию на ассемблер 16-битного процессора 8086 под DOS).

В этой части учебного курса мы рассмотрим основы создания процедур. Процедура представляет собой код, который может выполняться многократно и к которому можно обращаться из разных частей программы. Обычно процедуры предназначены для выполнения каких-то отдельных, законченных действий программы и поэтому их иногда называют подпрограммами. В других языках программирования процедуры могут называться функциями или методами, но по сути это всё одно и то же.

Команды CALL и RET

Ближние и дальние вызовы процедур

Существует 2 типа вызовов процедур. Ближним называется вызов процедуры, которая находится в текущем сегменте кода. Дальний вызов — это вызов процедуры в другом сегменте. Соответственно существуют 2 вида команды RET — для ближнего и дальнего возврата. Компилятор FASM автоматически определяет нужный тип машинной команды, поэтому в большинстве случаев не нужно об этом беспокоиться.

В учебном курсе мы будем использовать только ближние вызовы процедур.

Передача параметров

Очень часто возникает необходимость передать процедуре какие-либо параметры. Например, если вы пишете процедуру для вычисления суммы элементов массива, удобно в качестве параметров передавать ей адрес массива и его размер. В таком случае одну и ту же процедуру можно будет использовать для разных массивов в вашей программе. Самый простой способ передать параметры — это поместить их в регистры перед вызовом процедуры.

Возвращаемое значение

Кроме передачи параметров часто нужно получить какое-то значение из процедуры. Например, если процедура что-то вычисляет, хотелось бы получить результат вычисления. А если процедура что-то делает, то полезно узнать, завершилось действие успешно или возникла ошибка. Существуют разные способы возврата значения из процедуры, но самый часто используемый — это поместить значение в один из регистров. Обычно для этой цели используют регистры AL и AX. Хотя вы можете делать так, как вам больше нравится.

Сохранение регистров

Хорошим приёмом является сохранение регистров, которые процедура изменяет в ходе своего выполнения. Это позволяет вызывать процедуру из любой части кода и не беспокоиться, что значения в регистрах будут испорчены. Обычно регистры сохраняются в стеке с помощью команды PUSH, а перед возвратом из процедуры восстанавливаются командой POP. Естественно, восстанавливать их надо в обратном порядке. Примерно вот так:

Пример

Для рисования горизонтальной линии из символов предназначена процедура draw_line. В DL передаётся код символа, а в CX — количество символов, которое необходимо вывести на экран. Эта процедура не возвращает никакого значения. Для вывода 2-х символов конца строки написана процедура print_endline. Она вызывается без параметров и тоже не возвращает никакого значения. Коды символов для рисования рамок можно узнать с помощью таблицы символов кодировки 866 или можно воспользоваться стандартной программой Windows «Таблица символов», выбрав шрифт Terminal.

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

Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка

Отладчик Turbo Debugger

Небольшое замечание по поводу использования отладчика. В Turbo Debugger нажимайте F7 («Trace into»), чтобы перейти к коду вызываемой процедуры. При нажатии F8(«Step over») процедура будет выполнена сразу целиком.

Упражнение

Объявите в программе 2-3 массива слов без знака. Количество элементов каждого массива должно быть разным и храниться в отдельной 16-битной переменной без знака. Напишите процедуру для вычисления среднего арифметического массива чисел. В качестве параметров ей будет передаваться адрес массива и количество элементов, а возвращать она будет вычисленное значение. С помощью процедуры вычислите среднее арифметическое каждого массива и сохраните где-нибудь в памяти. Выводить числа на экран не нужно, этим мы займемся в следующей части.

Источник

RET Возврат из процедуры

RETF Возврат из дальней процедуры

Команда ret извлекает из стека адрес возврата и передает управление назад в программу, первоначально вызвавшую процедуру. Если командой ret завершается ближняя процедура, объявленная с атрибутом near, или используется модификация команды retn, со стека снимается одно слово- относительный адрес точки возврата. Передача управления в этом случае осуществляется в пределах одного программного сегмента. Если командой ret завершается дальняя процедура, объявленная с атрибутом far, или используется модификация команды retf, со стека снимаются два слова: смещение и сегментный адрес точки возврата. В этом случае передача управления может быть межсегментной.
В команду ret может быть включен необязательный операнд (кратный 2), который указывает, на сколько байтов дополнительно смещается указатель стека после возврата в вызывающую программу. Прибавляя эту константу к новому значению SP, команда ret обходит аргументы, помещенные в стек вызывающей программой (для передачи процедуре) перед выполнением команды call. Обе разновидности команды не воздействуют на флаги процессора.

push AX ;Параметр 1, передаваемый в
;подпрограмму
push SI ;Параметр 2, передаваемый в
;подпрограмму
call subr ;Вызов подпрограммы

subr proc near

;Извлечение из стека параметров
; (без изменения содержимого SP)
ret 4 ;Возврат в вызывающую
;программу и снятие со стека
;двух слов с параметрами
subr endp

Источник

RET Возврат из процедуры

RETF Возврат из дальней процедуры

Команда ret извлекает из стека адрес возврата и передает управление назад в программу, первоначально вызвавшую процедуру. Если командой ret завершается ближняя процедура, объявленная с атрибутом near, или используется модификация команды retn, со стека снимается одно слово- относительный адрес точки возврата. Передача управления в этом случае осуществляется в пределах одного программного сегмента. Если командой ret завершается дальняя процедура, объявленная с атрибутом far, или используется модификация команды retf, со стека снимаются два слова: смещение и сегментный адрес точки возврата. В этом случае передача управления может быть межсегментной.
В команду ret может быть включен необязательный операнд (кратный 2), который указывает, на сколько байтов дополнительно смещается указатель стека после возврата в вызывающую программу. Прибавляя эту константу к новому значению SP, команда ret обходит аргументы, помещенные в стек вызывающей программой (для передачи процедуре) перед выполнением команды call. Обе разновидности команды не воздействуют на флаги процессора.

push AX ;Параметр 1, передаваемый в
;подпрограмму
push SI ;Параметр 2, передаваемый в
;подпрограмму
call subr ;Вызов подпрограммы

subr proc near

;Извлечение из стека параметров
; (без изменения содержимого SP)
ret 4 ;Возврат в вызывающую
;программу и снятие со стека
;двух слов с параметрами
subr endp

Источник

MS-DOS и TASM 2.0. Часть 10. Команды ассемблера.

Ret ассемблер что это. %D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA %D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B9 DOS 1. Ret ассемблер что это фото. Ret ассемблер что это-%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA %D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B9 DOS 1. картинка Ret ассемблер что это. картинка %D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA %D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B9 DOS 1

Команды ассемблера и команды процессора.

Стоит пояснить, что если к вопросу подойти формально строго, то команды процессора и команды ассемблера — это не одно и то же. Ассеммблер — хоть и низкоуровневый язык программирования, но иногда он без спроса программиста «корректирует код под себя». Причём у каждого ассемблера (masm, tasm, fasm) это может быть по-разному. Самый яркий пример — команда ret. В ассемблерном коде мы запишем ret, а реальный ассемблер ассемблирует её как retf или retn 8. Может также изменяться код, добавлением в качестве выравнивания кода команды процессора nop (об этом ниже в статье) и т.п. Чтобы не усложнять суть вопроса, под понятиями команды процессора и команды ассемблера мы будем подразумевать одно и то же.

Команды процессора (команды ассемблера) в большинстве своём работают с аргументами, которые в ассемблере называются операндами. Система машинного кода процессоров Intel содержит более 300 команд (команды процессора, сопроцессора, MMX-расширения, XMM-расширения). С каждым новым процессором их количество растёт. Для того, чтобы профессионально программировать, не надо зубрить и разбирать все команды процессора. При необходимости можно воспользоваться справочником. В процессе чтения статей, вы поймёте, что основная суть знания ассемблера состоит не в доскональном знании всех команд, а в понимании работы системы.

Не следует забывать, что команды процессор видит в виде цифр, которые можно рассматривать как данные. Например, команда NOP занимает один байт и её машинный код — 90h.

Начиная изучать язык низкого уровня, мы будем иметь дело с ограниченным набором старых-добрых команд процессора. Иные команды ассемблера понадобятся специалистам, заинтересованным в оптимизацией кода, связанного со сложными математическими расчетами данных большого объёма.

Основные (т.н. целочисленные) команды ассемблера позволяют написать практически любую программу для операционных систем MS-DOS и Windows. Количество команд ассемблера, которыми вы будете пользоваться будет расти со временем прохождения курса. Для более детального понимания, в последствии можете обратиться к справочнику команд.

Рассмотрим команды ассемблера на практическом примере.

С использованием среды разработки TASMED или любого текстового редактора набираем код. Программа, задаст вопрос на английском языке о половой принадлежности (имеется ввиду ваш биологический пол при рождении). Если вы нажмете m (Man), будет выведено приветствие с мужчиной, если w (Woman), то с женщиной, после этого программа прекратит работу. Если будет нажата любая другая клавиша, то программа предположит, что имеет дело с гоблином, не поверит и будет задавать вам вопросы о половой принадлежности, пока вы не ответите верно.

Источник

FE23 LOOCH DISASM


СПРАВОЧНИК ПО КОМАНДАМ
ПРОЦЕССОРОВ x86


Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка
ГлавнаяЗагрузкаИнструкцияКоманды x86Карта сайта

Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка
Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинкаRet ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка

ПЕРЕДАЧИ УПРАВЛЕНИЯ
И ВЫЗОВЫ ПРОЦЕДУР

К группе «Переходы и процедуры» в данном справочнике отнесены следующие пять команд:

КомандаВыполняемая операция
Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка
JMPБезусловная передача управления
CALLВызов процедуры
RETВозврат из процедуры
ENTERОбразование стекового кадра для параметров процедуры
LEAVEОтмена действия команды ENTER перед выходом из процедуры

Команда безусловной передачи управления


КомандаТип переходаОперандКодФормат
Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка
( 0 )JMPSHORT(rel8)EB
( 1 )JMPNEAR(rel16)
(rel32)
E9
( 2 )JMPNEAR,
косвенный
(r/m16)
(r/m32)
FF /100
( 3 )JMPFAR(ptr16:16)
(ptr16:32)
EA
( 4 )JMPFAR,
косвенный
(r/m16)
(r/m32)
FF /101

В колонке «Операнд» показано, что является операндом для машинной команды. Размер операнда 16 бит или 32 бита определяется атрибутом размера операнда.

Вариант ( 0 ). Для короткого SHORT перехода смещение занимает всего 1 байт. Поэтому переход может быть только в пределах от (-128) до (+127).

Вариант ( 1 ). Для близкого NEAR перехода смещение занимает 2 байта или 4 байта. Если смещение из двух байт, переход возможен в пределах от (-32768) до (+32767).

Вариант ( 2 ). Переход косвенный. В команде задан не адрес перехода, а то место (регистр или место в памяти), где можно найти адрес перехода.

В первых трех вариантах переход происходит в пределах того же самого сегмента, в котором выполняется команда JMP. При таком переходе содержимое регистра CS не изменяется.

В следующих двух вариантах выполняется далекий FAR переход (межсегментный).

Вариант ( 3 ). В машинной команде задан полный указатель, то есть, задан сегмент и адрес в этом сегменте. В режие «16 бит» полный указатель (ptr16:16) занимет четыре байта, в режие «32 бита» полный указатель (ptr16:32) занимает шесть байт.

Вариант ( 4 ). Переход косвенный. В команде задан не адрес перехода, а то место, где можно найти полный указатель для перехода. Это место непременно должно быть в памяти, а не в регистре, так как в регистре полный указатель не помещается.

Команда вызова процедуры


КомандаТип переходаОперандКодФормат
Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка
( 1 )CALLNEAR(rel16)
(rel32)
E8
( 2 )CALLNEAR,
косвенный
(r/m16)
(r/m32)
FF /010
( 3 )CALLFAR(ptr16:16)
(ptr16:32)
9A
( 4 )CALLFAR,
косвенный
(r/m16)
(r/m32)
FF /011

Нетрудно заметить, что эта таблица для команды CALL очень похожа на предыдущую таблицу для команды JMP. Отличие только в том, что для команды CALL нет варианта с адресом типа SHORT.

Остальные четыре варианта полностью одинаковые для команды JMP и для команды CALL. Полностью совпадают типы перехода, типы операнда, формат машинной команды. (Понятно, что коды операций для команд JMP и CALL разные).

При далеких FAR вызовах процедуры в стеке сохраняется еще и значение сегмента CS, причем в стек сначала заносится CS, а затем EIP (или IP для режима «16 бит»).

Команда возврата из процедуры


КомандаТипОперандКодФормат
Ret ассемблер что это. . Ret ассемблер что это фото. Ret ассемблер что это-. картинка Ret ассемблер что это. картинка
RET/RETNNEARC3
RET/RETNNEAR(imm16)C2
RET/RETFFARCB
RET/RETFFAR(imm16)CA

Имеется четыре разных кода операции для команды RET, эти машинные команды выполняются немного по-разному.

При близком NEAR возврате из стека извлекается значение для EIP, при этом значение CS остается неизменным. При далеком FAR возврате из стека извлекается значение для EIP, а затем значение для CS.

На языке ассемблера у команды RET может быть необязательный численный параметр, который показывает, сколько байт (для режима «16 бит») или слов (для режима «32 бита») нужно дополнительно освободить в стеке после извлечения из стека адреса для возврата. Таким образом в стеке освобождается место, которое занимали параметры процедуры. (Обычно перед вызовом процедуры в стек заносятся значения параметров этой процедуры).

Команды стекового кадра

Команда ENTER ставится в начале процедуры. Она подготавливает стековый кадр к работе. Команда LEAVE ставится перед выходом из процедуры, причем ставится перед каждой командой RET, если выходов несколько. Она восстанавливает прежнюю ситуацию в стеке.

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

Источник

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

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