Эта статья предназначена для тех, кто только начинает изучать язык ассемблера. Довольно часто можно встретить книги и статьи с заголовками вроде «Ассемблер это просто». Подобные слоганы — не более чем маркетинговый ход — нужно как-то привлекать клиентов (читателей). Конечно, научиться писать простые программы очень легко. Но все зависит от задач, которые вы перед собой ставите. Научиться водить машину легко. Однако бывает только один водитель-ас.
Думаю, вы уже знакомы с программированием — вы знаете любой из языков высокого уровня (C, PHP, Java, JavaScript и т. д), Вы работали с шестнадцатеричными числами, плюс вы знаете, как использовать командную строку в Windows , Linux или macOS.
Знаете ли вы что такое 8088? Это дедушка всех компьютерных процессоров! И живой дедушка. Я бы сказал — бессмертный и постоянный. Если из вашего процессора, будь то Ryzen, Core i9 или какого-то другого типа, вырвите все застрявшие там гаджеты под влиянием технического прогресса, то старый добрый 8088 останется.
SGX, ММХ, 512-битные регистры SIMD и другие нововведения приходят и уходят.Но дедушка 8088 остался без изменений. Сначала подружитесь с ним. Тогда вы легко справитесь с любыми гаджетами вашего процессора.
Когда же вам придется начать с самого начала, то есть сначала выучить классический набор инструкций 8088, а затем постепенно познакомитесь с современными функциями — в какой-то момент вы начнете видеть нестандартные способы использования этих самых функций.
После запуска программного обеспечения и загрузки его операционной системой в ОЗУ процессор обращается к первому байту программы. Выцепляет инструкцию оттуда и выполняет ее, а после ее выполнения переходит к следующей. И так до конца программы.
Некоторые инструкции имеют объем в один байт, а некоторые – в два, три или больше.Это выглядит как то так:
90
B0 77
B8 AA 77
C7 06 66 55 AA 77
Вернее, даже так:
90 B0 77 B8 AA 77 C7 06 66 55 AA 77
И только машина способна понять такое.Так что еще несколько лет назад разработчики придумали более гуманный способ общения с компьютером: они создали ассемблер.
С помощью ассемблера можно теперь не танцевать с бубном вокруг шестнадцатерных чисел, а и писать инструкции в мнемонике:
nop
mov al, 0x77
mov ax, 0x77AA
mov word [0x5566], 0x77AA
Но ведь и читать-то это намного проще! С другой стороны, если ты увидел ассемблерный код впервые и не знаешь, как его интерпретировать, то такая мнемоника для тебя, скорей всего, тоже будет не ясна.
Какие функции выполняет инструкция Mov? Присваивает число, которое указано справа, переменной, которая указана слева.
Регистр процессора или ячейка ОЗУ – это одна из переменных в памяти компьютера. Процессор быстрее работает с регистрами, чем с памятью, потому что регистры находятся внутри него. Но у процессора мало регистров, поэтому в любом случае что-то нужно хранить в памяти.
Когда ты программируешь на ассемблере и создаешь программу для ее обработки, ты сам решаешь какие переменные хранить в памяти,а какие в регистрах. Для решения этой задачи в языках высокого уровня используется компилятор.
У процессора 8088 регистры 16-битные, их восемь штук (в скобках указаны типичные способы применения регистра):
AX
— общего назначения (аккумулятор);BX
— общего назначения (адрес);CX
— общего назначения (счетчик);DX
— общего назначения (расширяет AX
до 32 бит);SI
— общего назначения (адрес источника);DI
— общего назначения (адрес приемника);BP
— указатель базы (обычно адресует переменные, хранимые на стеке);SP
— указатель стека.Хотя каждый регистр имеет типичный вариант использования, вы можете использовать их как хотите. Первые четыре регистра — AX, BX, CX и DX — при желании можно использовать не полностью, а половинками по 8 бит (старший H и младший L): AH, BH, CH, DH и AL, BL, CL, DL. Например, если вы напишете в AX число 0x77AA (mov ax, 0x77AA), то 0x77 попадет в AH, а 0xAA — в AL.
Теория пока закончена. Сейчас мы с тобой подготовим рабочее место и напишем программу «Hello World!» для того, чтобы понять, как эта теория работает на практике.
Скачай компилятор NASM с www.nasm.us. Обрати внимание, он работает на всех современных ОС: Windows 10, Linux, macOS. Распакуй NASM в какую-нибудь папку. Чем ближе папка к корню, тем удобней. У меня это c:\nasm
(я работаю в Windows). Если у тебя Linux или macOS, можешь создать папку nasm
в своей домашней директории.
Тебе надо как-то редактировать исходный код. Ты можешь пользоваться любым текстовым редактором, который тебе по душе: Emacs, Vim, Notepad, Notepad++ — сойдет любой. Лично мне нравится редактор, встроенный в Far Manager, с плагином Colorer.
Чтобы в современных ОС запускать программы, написанные для 8088, и проверять, как они работают, тебе понадобится DOSBox или VirtualBox.
Сейчас ты напишешь свою первую программу, которая будет написана на ассемблере.
Если вы не понимаете, что здесь написано, не волнуйтесь. А пока попробуйте к ассемблерному коду привыкнуть, пощупайте пальцами. Я все объясню ниже. Кроме того, студенческая мудрость гласит: «Ты что-нибудь понимаешь? Перечитал и переписал несколько раз. Сначала непонятное станет знакомым, а потом знакомое станет понятным. «
Для запуска командной строки, в Windows есть cmd.exe. Теперьнужно зайти в папку nasm и скомпилировать программу, используя вот такую команду:
nasm -f bin first.asm -o first.com
Если все сделано правильно то она не будет вызывать никаких проблем с компиляцией и запуском, и в командной строке не появится никаких сообщений. NASM просто создаст файл first.com и выйдет.
Чтобы запустить этот файл в современной ОС, открой DOSBox и введи туда вот такие три команды:
mount c c:\nasm
c:
first
Само собой, вместо c:\nasm
тебе надо написать ту папку, куда ты скопировал компилятор. Если ты все сделал правильно, в консоли появится сообщение «Hello, world!».
В нашей программе есть только три вещи: инструкции, директивы и метки.
Инструкции. Вы уже знакомы с инструкциями (мы рассмотрели их немного раньше) и знаете, что это мнемоника, которую компилятор переводит в машинный код.
Директивы (у нас их две:org
и db
)- это команды, которые вы даете компилятору. Взятые по отдельности, каждая директива сообщает компилятору, что на этапе сборки необходимо то-то и то-то действие. Директива не переводится в машинный код, но влияет на то, как генерируется машинный код.
Директива org сообщает компилятору, что все последующие инструкции не должны размещаться в начале сегмента кода, а должны отклоняться от начала такого количества байтов (в нашем случае 0x0100).
Директива db указывает компилятору вставить байтовую строку в ваш код. Здесь мы указываем через запятую, что туда помещать. Это может быть строка (в кавычках), символ (в одинарных кавычках) или просто число.
В нашем случае: db "Hello, world", '!', 0
.
Убедитесь, что я вырезал восклицательный знак на остальной части строки, чтобы показать, что вы можете работать с отдельными символами в директиве db.
В общем, лучше писать так:
db "Hello, world!", 0
Метки используются для двух целей: для задания имен переменных, которые хранятся в памяти (в нашей программе есть только одна такая метка: string), и для обозначения участков кода, в которых вы переходите из других мест в программе ( В нашем ассортименте три таких лейбла — те, которые начинаются с двух символов-собак).
Что значит «прыгать с других мест в программе»? Процессор обычно выполняет инструкции последовательно, одну за другой. Но если вы хотите организовать ветвление (условие или цикл), вы можете использовать инструкцию ветвления. Вы можете перейти вперед от текущей инструкции или назад.
У тебя в распоряжении есть одна инструкция безусловного перехода (jmp
) и штук двадцать инструкций условного перехода.
Мы используем две инструкции перехода: je
и jmp
. Первый выполняет условный переход (Jump if equal — прыгать, если равен), второй (Jump) — безусловный. С их помощью мы организовали цикл.
Обратите внимание, что метки начинаются с буквы, подчеркивания или собаки. Вы также можете вставлять числа, но не в начале. В конце метки необходимо поставить двоеточие.
Итак, в нашей программе всего три вещи: инструкции, директивы и метки. Но может быть еще одна важная вещь: комментарии. Они значительно облегчают чтение исходного кода.
Как добавлять комментарии? Просто поставьте точку с запятой, и все, что вы напишете после нее (до конца строки), будет комментарием. Добавим комментарии к нашей программе.
Теперь, когда ты разобрался во всех частях программы по отдельности, попробуй вникнуть, как все части служат алгоритму, по которому работает наша программа.
BX
адрес строки.AL
очередную букву из строки.Мы не можем использовать AX для хранения адресной информации, так как нет таких инструкций, которые бы использовали его в качестве регистра-источника.
Если программа не может взаимодействовать с пользователем и выполнять его команды, то она бесполезна.Смотри, как можно считывать данные с помощью клавиатуры.Сохрани вот этот код как second.asm.
Потом иди в командную строку и скомпилируй его в NASM:
nasm -f bin second.asm -o second.com
Затем запусти скомпилированную программу в DOSBox:
second
Как работает программа? Две строки после метки @@ start вызывают функцию BIOS, которая считывает символы с клавиатуры. Он ожидает, пока пользователь нажмет клавишу, а затем помещает ASCII-код полученного значения в регистр AL. Например, если вы нажмете заглавную A, 0x41 попадет в AL, а если вы нажмете заглавную a, 0x61.
Затем смотрим: если нажата клавиша с кодом 0x1B (клавиша ESC), мы выходим из программы. Если клавиша ESC не нажата, мы вызываем ту же функцию, что и в предыдущей программе, чтобы показать символ на экране. После показа — перейти в начало (jmp): start.
На заметку, инструкция cmp (от слова Compare — сравнивать) выполняет сравнение, инструкция je(Jump if Equal) – прыжок в конец программы.
Если тебе интересно, в какой машинный код преобразуются инструкции программы, скомпилируй исходник вот таким вот образом (добавь опцию -l
):
nasm -f bin second.asm -l second.lst -o second.com
Тогда NASM создаст не только исполняемый файл, но еще и листинг: second.lst
. Листинг будет выглядеть как-то так.
Вы, наверное, уже устали вводить длинную последовательность одних и тех же букв в командную строку каждый раз при компиляции. Если вы используете Windows, вы можете создать командный файл (например, m.bat) и вставить в него следующий текст.
Теперь ты можешь компилировать свою программу вот так:
m first
Само собой, вместо first
ты можешь подставить любое имя файла.
В общем теперь ты знаешь как написать простейшю программе на ассемблере как ее скомпилировать и какие средства для этого нужны. Однако, если ты прочтешь одну статью, то вряд ли станешь настоящим программистом на ассемблере.Чтобы создать и написать на нем что-то действительно стоящее – например, Floppy Bird и “МикроБ”, тебе еще придется немало потрудиться. Но это уже твой первый шаг в этом направлении.
Чтобы взломать сеть Wi-Fi с помощью Kali Linux, вам нужна беспроводная карта, поддерживающая режим мониторинга…
Работа с консолью считается более эффективной, чем работа с графическим интерфейсом по нескольким причинам.Во-первых, ввод…
Конечно, вы также можете приобрести подписку на соответствующую услугу, но наличие SSH-доступа к компьютеру с…
С тех пор как ChatGPT вышел на арену, возросла потребность в поддержке чата на базе…
Если вы когда-нибудь окажетесь в ситуации, когда вам нужно взглянуть на спектр беспроводной связи, будь…
Elastic Security стремится превзойти противников в инновациях и обеспечить защиту от новейших технологий злоумышленников. В…