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

Команды ассемблера - справочник T_HELP (XVIEW.EXE).

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

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

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

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

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

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

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

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

Анализируем ассемблерный код.

В програме используются следующие команды ассемблера:

  • mov
  • cmp
  • jmp (jcc)
  • call
  • ret
  • int

Согласитесь, не так уж и много! На примере четырёх команд ассемблера (mov, cmp, jmp, int) попробуем сформировать общее понимание и выработать алгоритм практической работы. Основное предназначение команд call и ret — работа с процедурами и их мы рассмотрим в следующей статье.

Английский язык — язык программистов и его знать просто необходимо. команды процессора чаще всего представляют сокращённые названия смыслового характера. Смысл операции заложен в ассемблерной команде.

MOV (MOVe operand — переместить операнд).

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

mov приёмник, источник.

CMP (CoMPare operands — сравнить операнды).

Для сравнения операндов используется вычитание (это полезно знать изучая команду jcc), значения операндов не меняются:

cmp операнд1, операнд2

обычно используется для организации условных переходов с командами jmp и jcc (jcc).

JMP (JuMP — прыгнуть, мгновенно перейти).

Продолжить выполнение кода с указанной метки:

jmp метка

JCC (Jump if conditions — перепрыгнуть, перейти если выполняется условие).

Переход к указанной метке выполняется при осуществлении определённого условия. Практически програмист сталкивается с множеством разновидностей команды (ja,je,jl,jna jz,jpe и т.д. — смотри справочник). Фактически команда проверяет состояние флагов и если условие выполняется, осуществляет переход к метке:

jcc метка

В нашей программе мы используем JE (Jump if Equal), соответственно есть условный переход JNE (Jump if Not Equal). Что любопытно, в данном случае проверяется состояние флага нуля (ZF). Алгоритм работы JE следующий:

  • если ZF=1, то перейти к метке, если нет, то продолжить выполнение следующего шага программы.
  • команда JE полностью эквивалентна команде JZ (Jump if Zero), а команда JNE (Jump if Not Equal) — команде JNZ (Jump if Not Zero).
  • если ZF=0, то перейти к метке, если нет, то продолжить выполнение следующего шага программы.

INT (INTerrupt — вызов подпрограммы прерывания).

Имеется ввиду, что ваша программа прерывается и вызывается подпрограмма под определённым номером:

int номер прерывания.

Через функции прерываний (или просто «прерывания DOS») реализован так называемый DOS API (Application Programing Interfaces). В данном случае подпрограмма просто обозначена номером. В операционной системе Windows подпрограммы (системные функции Win API) имеют осмысленные названия (например, GetCurrentDirrectory, MessageBox, SetDlgItemText).

Прерывания DOS.

В DOS необходимо пользоваться справочником. Наиболее удобный и совершенный из известных — T_HELP (смотрите рисунок в начале статьи, сам справочник есть в архиве — папка T_HELP). Есть прерывание DOS, а есть BIOS. Прерывания зависят от версии DOS. Чтобы вызвать функцию прерывания, необходимо подготовить соответствующие регистры. Обычно — это AX (ah, al) Члены, а также выходные значения функций передаются именно через них.

Разобраться с T_HELP можете сами. Наиболее удобно изучать функции с использованием API Index. Например, запускаем …T_HELP\XVIEW.EXE:

  • TECH Topics
  • DOS Interrupts
  • INT 21H DOS Services
  • DOS Function Index (by number)Ищем в табличном списке прерывание 4CH, кликаем по нему левой клавишей мыши и изучаем подробную справку:

Dos Fn 4cH : Terminate Program
AH 4CH
AL Exit Code


ну и тд.

На последок, посмотрим, как выглядит наша программа, обработанная дебагером, встроенным в HIEW (Alt+P):

Обратите внимание, как HIEW отображает информацию:

0000000F: 3C77 cmp al,077 ;«w» — в качеестве комментария отобразил ASCII символ, сответствующий 077h

00000018: C70648013001 mov w,[00148],00130 ;» 0″ — обозначил, что по смещению [00148] находятся данные размером в слово (w) и заполнил
;его нулём (addrs dw 0);

00000016: EBE8 jmps 000000000 ——— (4) ; Jump Short — обозначен именно ближний переход.

00000020: 90 nop ; а это что за команда? У нас её не было!

При исследовании кода обнаружилась «лишняя» команда NOP.

NOP (No OPeration — нет операции).

Не производит никаких действий. Занимает один байт (машинный код — 90h) и используется для:

  • Выравнивания следующей команды или переменной сегмента в целях увеличения быстродействия определённых процессоров (иногда актуально).
  • Резервирования «пустого» места в коде.
  • Для задержки в целях синхронизации работы компьютера (сейчас не актуально).
  • При отладке.

В данном случае команду NOP вставил TASM, посчитав, что такой код будет работать быстрее. Мы уже говорили, что определённым процессорам легче работать с определенными блоками данных. Именно для решения вопроса «блочности» в данном случае TASM сгенерировал такой код.

Команда NOP очень часто используется хакерами, чуть позже мы покажем, в каких целях.

Мы рассмотрели наиболее часто встречающиеся команды ассемблера, уяснили принцип их использования. В следующей статье нас ждут процедуры и команды, которые помогают их организовывать. Напоминаем, что все необходимые программы можно скачать с нашего сайта.

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