Ассембли. Урок I - Вызовы API Привет. Итак приступим к делу, для этого нам нужно скачать какой-нибудь компилятор ассемблера, качайте или FASM или MASM, так как отличия в синтаксисе минимальны. Скачать их можно тут в соответствующем разделе. Лучше конечно скачать FASM, так как этот компилятор нравиться мне больше остальных и обьяснять я буду именно на нём. Итак, давайте напишем приложение которое будет показывать простое окошко с какой-либо фразой, как и подобает обучаться програмированию. Вообще я сомневаюсь что имеено так нужно учиться но не будем нарушать традиций. Создадим простой текстовый файлик и назовём его "first.asm" и начинаем программировать: Что делает этот код? Да ничего... Если мы его скомпилируем то получим полноценную программу которая просто завершает сама себя. Компилируем: fasm.exe first.asm Итак, вы попытались скомпилировать... Но не получилось, а всё потому что компилятор не знает где находиться файл-инклудник - "win32ax.inc". Необходимо ему явно указать этот файл для этого меняем код программы, например вот так: Теперь всё скомпилируеться отлично, но чтобы это не писать каждый раз, можно задействовать переменные среды, присвоив например переменной %inc% путь "D:\FASM\include". Но этим мы займемся в следующем туториале, так как в этом я собираюсь показать как вызываеться функция Windows API (какой и являеться ExitProcess). Кстати invoke - это макрос, который обьявлен в инклуднике win32ax.inc. Он позволяет нам вызывать функции привычным образом как например в С++ или Delphi. Без него мы будем писать в следующих туториалах. Короче усвойте что invoke это вызов функций (но только на первый туториал, ну или на все если в будущем вы собираетесь программировать именно с его помощью). Теперь давайте добавим в нашу программу ещё одну функцию - MessageBox: Первый параметр функции MessageBox являеться дескриптор окна-родителя нашего окошка, в качестве него мы передаём константу HWND_DESKTOP - дескриптор Рабочего Стола. Второй параметр - адрес на текст самого окошка. Возникает вопрос - почему же мы не пишем: invoke MessageBox,HWND_DESKTOP,offset Message....? Да потому что, макрос invoke достаточно универсален, чтобы принимать в параметре просто текст... Подробнее обьясню в следующих уроках. Третий параметр - заголовок окна, то есть его адрес. Ну а четвёртый параметр - стиль окна, у нас это MB_ICONASTERISK то есть окошко с восклицанием. Кстати дополнительную информацию об API - можно получить либо на MSDN либо из любой справки Windows SDK, которая поставляеться с любым продуктом Borland. Вот и написали и разобрали вызов функций и написали полноценное приложение. Всё, до следующего туториала, всего хорошего...
Ассембли. Урок II - Циклы и условные переходы Привет. Сегодня поговорим о циклах и условных переходах. Для этого давайте возьмём код из первого урока и немного его усложним, добавив сначала цикл, затем условный переход. Давайте сделаем так чтобы окошко вызывалось 5 раз. Для этого приведём следующий код: Тут наверное стоит пояснить что метка @@loop - так написанна для удобства и только для этого. Есть ещё понятие анонимных меток - о них мы поговорим в следующих уроках. Итак из комментариев в коде я думаю всё ясно. Мы просто обьявили регистр esi как счётчик, затем мы вызываем окошко и уменьшаем счётчик на 1 (dec - уменьшить на 1). Сравниваем счётчик с нулём, так мы проверяем, не кончился ли счётчик, и если не кончился - переходим на метку @@loop. Поясню, что JA - Jump if Above то есть переход если больше. Так и получаеться что пока в esi больше нуля то мы "бегаем по коду" и выполняем вызов окна. Как только счётчик установлен в 0 (нуль) - выполнение программы прекращаеться, то есть выполняеться ExitProcess. Кстати в этой программе мы использовали и цикл и условный переход. Но давайте превратим этот код в более привычный вид для программистов на C++ и Delphi: Тут уже попонятнее да? Появился привычный нам всем if. Как вы уже знаете после if выполняеться код если условие верно. То есть если у нас esi = 0, то выполняеться ExitProcess. Тут всё понятно и так.
Ассембли. Урок III - Сравнения и переходы (более подробно) Привет. На этом уроке поговорим про операторы cmp & условные переходы более подробно. Для начала обратите внимание на таблицу условных переходов. Вы уже видели нечто подобное на прошлом уроке: Теперь давайте посмотрим на практике. Есть код: Разберём каждую инструкцию: 1) mov - инструкция, которая присваивает значения. В данном случаи мы присваиваем регистру EAX число 32h (hex) 2) Аногогично, только теперь регистру EBX присваиваеться 33h 3) cmp - оператор сравнения (Compare - сравнивать). Сравнивает EAX c EBX и взависимости от результата выставляет соответствующие арифметические флаги (у нас ZF, SF, CF - но не подумайте что это все флаги!) 4) Наш условный переход, чтобы его понять обратимся к таблице. Смотрим тип операндов - любые, значит не имеет значения, со знаком числа или без. Далее смотрим критерий условного перехода - 1операнд НЕ РАВЕН 2операнду. И третие - смотрим значение флага, в данном случаи это флаг "нуля" (ZF - Zerro Flag). Итак из таблицы видно что, чтобы мы прыгнули на метку - регистры EAX & EBX не должны быть равны и флаг нуля устанавливаеться в 0(нуль). То есть если они не равны - мы прыгаем на метку "metka" 5) Так как переходу быть - процессор не выполняет эту инструцкию. Она предназначена для вычитания. То есть если бы перехода не было она бы вычла из EAX, EAX (значения) - тем самым обнулив его. 6) Уже до боли знакомый вам вызов функции API ExitProcess, который просто завершит программу. Если бы мы в 4) пункте написали бы не JNE a JZ то мы бы не прыгнули на метку, так как регистры EAX & EBX не равны между собой. Для полноты всей картины давайте воспроизведём всё выше описаное в полноценную программу: Вот и весь урок. Можно эксперементировать задавая разные значения регистрам и изменяя прыжок - так вы быстрее поймёте. Есстественно нужно это делать в отладчике. Возьмите Olly. Кстати вот этот наш кусок кода в отладчике выглядит следующим образом: Красная стрелочко означает что сейчас произойдёт переход, и я ещё там написал что флаг нуля = 0 (нуль), чтобы не постить весь экран от Olly. А вот Olly лучше скачайте и посмотрите сами!
Ассембли. Урок IV - Переменные и возвращаемые значения функций Приветствую... Сегодняшний урок посвящённ переменным и значениям, которые возвращают функции API. Для более подробного понимания материала воспользуемся всё той-же функцией MessageBox. Вы можете спросить: что может возвращать простое окно сообщения? А возвращает она одно из следующих значений: IDABORT ; нажата кнопка ABORT IDCANCEL ; нажата кнопка CANCEL IDIGNORE ; нажата кнопка IGNORE IDNO ; нажата кнопка NO IDOK ; нажата OK IDRETRY ; нажата RETRY IDYES ; нажата кнопка YES Более подробную информацию по функциям API можно найти на MSDN (http://msdn2.microsoft.com/ru-ru/default.aspx), или в любом справочнике который поставляеться с продуктами от Borland. Посмотрим на следующий код: Посмотрите стиль окошка - MB_OK, соответственно окошко выскочит с одной кнопкой OK. И если мы нажмём OK то функция возвратит IDOK. Но что если нам нужно например использовать две кнопки, например OK & CANCEL. Для этого есть специальный стиль окна - MB_OKCANCEL. Вообще они конечно описаны в MSDN, так что я не буду их приводить в этом тексте. Пример: Тогда, соответственно при выполнении этого кода, если мы нажали на OK, функция возвратит IDOK, если CANCEL - то получим IDCANCEL. Чтобы узнать что возвращает та или иная функция - обратитесь к MSDN (для этого знание технического английского вам поможет). Кстати функции возвращают значения через регистр EAX почти всегда. Так что, чтобы проверить возвращаемое значение - нужно проверить именно регистр EAX. Давайте сделаем проверку, при которой если мы нажимаем например на OK выскакивает окошко и говорит нам что мы нажали именно эту кнопку, если CANCEL - то соответственно сообщение будет другим: Надеюсь из комментариев всё ясно, но на всякий случай поясню, что после того как мы вивели окно с приветствием, мы проверяем с помощью оператора CMP, значение регистра EAX и если там IDOK то прыгаем на сообщение и говорим что нажали OK, иначе выводим сообщение что нажали CANCEL и прыгаем на метку EXIT дабы избежать появления второго окна, ведь код продолжит выполняться и наткнёться на строку invoke MessageBox,0,'вы нажали OK','заголовок',MB_OK . То есть инструкцией jmp (безусловный переход) мы перепрыгиваем эту запись и выходим из программы. Теперь займёмся переменными: Переменные должны быть обьявлены в секции данных - .data . Сначала мы пишем имя переменной потом через пробел - её размер, и только потом через пробел её значение. Пример: В этом примере мы обьявили переменную perem1 размером в 4 байта (dd - define dword (двойное слово - 4 байта)) и присвоили ей значение 0 (нуль). Теперь в неё можно писать данные, но не более 4 байт, так как мы задали размер именно в 4 байта. Можно считывать значение переменной итд. Кстати, для того чтобы считать значение переменной, её нужно обрамить скобками вот так: Но чтобы считать её адрес в памяти - обрамление скобками не требуеться. Пример: Давайте теперь примерим всё это на практике. Напимеш программу для вывода текста в окно при помощи переменных. Для этого рассмотрим параметры самой функции, которые кстати вы можете и сами посмотреть в MSDN, но у меня мало трафика и я приведу кусок из справки от Borland: int MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); Из этого ясно что: Для текста в заголовке и для текста в окне, мы должны передавать не значения, а адреса переменных, которые этот текст содержат. Сделаем это: Обратите внимание как мы обьявляем строки - как массив байтов, которые заканчиваються нулевым байтом. Кстати db - это обьявить байт. Заметьте также, что когда мы вызываем функцию - мы не обрамляем переменные скобками, то есть мы берём их адрес в памяти, а не их значения. Вот и всё. Пока... ------------------------------------------------------------------- Вроде всё доходчиво описано... поймёт каждый. =)
реально, если б небыл знаком - хрен бы что понял. Первый урок - работа с Api, второй циклы - вобще улыбнуло. Поюзайте уроки Калашникова, их очень хвалят.