Ассемблер для новичков.

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by luz3r, 13 Aug 2008.

  1. luz3r

    luz3r Banned

    Joined:
    23 Feb 2008
    Messages:
    119
    Likes Received:
    250
    Reputations:
    -11
    Ассембли. Урок 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. Вот и написали и разобрали вызов функций и написали полноценное приложение. Всё, до следующего туториала, всего хорошего...
     
    #1 luz3r, 13 Aug 2008
    Last edited: 13 Aug 2008
    3 people like this.
  2. Piflit

    Piflit Banned

    Joined:
    11 Aug 2006
    Messages:
    1,249
    Likes Received:
    585
    Reputations:
    31
    ого. прям в строчку. жестко
     
  3. luz3r

    luz3r Banned

    Joined:
    23 Feb 2008
    Messages:
    119
    Likes Received:
    250
    Reputations:
    -11
    Ассембли. Урок II - Циклы и условные переходы

    Привет. Сегодня поговорим о циклах и условных переходах. Для этого давайте возьмём код из первого урока и немного его усложним, добавив сначала цикл, затем условный переход. Давайте сделаем так чтобы окошко вызывалось 5 раз. Для этого приведём следующий код:

    Тут наверное стоит пояснить что метка @@loop - так написанна для удобства и только для этого. Есть ещё понятие анонимных меток - о них мы поговорим в следующих уроках. Итак из комментариев в коде я думаю всё ясно. Мы просто обьявили регистр esi как счётчик, затем мы вызываем окошко и уменьшаем счётчик на 1 (dec - уменьшить на 1). Сравниваем счётчик с нулём, так мы проверяем, не кончился ли счётчик, и если не кончился - переходим на метку @@loop. Поясню, что JA - Jump if Above то есть переход если больше. Так и получаеться что пока в esi больше нуля то мы "бегаем по коду" и выполняем вызов окна. Как только счётчик установлен в 0 (нуль) - выполнение программы прекращаеться, то есть выполняеться ExitProcess.

    Кстати в этой программе мы использовали и цикл и условный переход. Но давайте превратим этот код в более привычный вид для программистов на C++ и Delphi:

    Тут уже попонятнее да? Появился привычный нам всем if. Как вы уже знаете после if выполняеться код если условие верно. То есть если у нас esi = 0, то выполняеться ExitProcess. Тут всё понятно и так.
     
  4. luz3r

    luz3r Banned

    Joined:
    23 Feb 2008
    Messages:
    119
    Likes Received:
    250
    Reputations:
    -11
    Ассембли. Урок III - Сравнения и переходы (более подробно)

    Привет. На этом уроке поговорим про операторы cmp & условные переходы более подробно. Для начала обратите внимание на таблицу условных переходов. Вы уже видели нечто подобное на прошлом уроке:

    [​IMG]

    Теперь давайте посмотрим на практике. Есть код:

    Разберём каждую инструкцию:

    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. Кстати вот этот наш кусок кода в отладчике выглядит следующим образом:

    [​IMG]

    Красная стрелочко означает что сейчас произойдёт переход, и я ещё там написал что флаг нуля = 0 (нуль), чтобы не постить весь экран от Olly. А вот Olly лучше скачайте и посмотрите сами!
     
  5. luz3r

    luz3r Banned

    Joined:
    23 Feb 2008
    Messages:
    119
    Likes Received:
    250
    Reputations:
    -11
    Ассембли. Урок 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 - это обьявить байт. Заметьте также,

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



    -------------------------------------------------------------------
    Вроде всё доходчиво описано... поймёт каждый. =)
     
    #5 luz3r, 13 Aug 2008
    Last edited: 13 Aug 2008
    1 person likes this.
  6. GALIAFF

    GALIAFF Elder - Старейшина

    Joined:
    28 Sep 2007
    Messages:
    45
    Likes Received:
    28
    Reputations:
    5
    уебись =\
     
  7. furang

    furang Elder - Старейшина

    Joined:
    7 Apr 2007
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    Нафиг переделывать уроки iczelion-а, тем более у него они лучше получились.
     
  8. neprovad

    neprovad Elder - Старейшина

    Joined:
    19 Oct 2007
    Messages:
    899
    Likes Received:
    274
    Reputations:
    59
    Повторение - мать учения. Кто-то может быть ни разу не видел эти пресловутые уроки от iczelion'а
     
  9. NorB

    NorB Elder - Старейшина

    Joined:
    20 Jul 2007
    Messages:
    109
    Likes Received:
    12
    Reputations:
    -2
    wasm.ru и некаких вапросов!=)
     
  10. Midas

    Midas Elder - Старейшина

    Joined:
    17 Jan 2008
    Messages:
    241
    Likes Received:
    45
    Reputations:
    1
    реально, если б небыл знаком - хрен бы что понял. Первый урок - работа с Api, второй циклы - вобще улыбнуло.

    Поюзайте уроки Калашникова, их очень хвалят.
     
    1 person likes this.
  11. z01b

    z01b Муджахид

    Joined:
    5 Jan 2007
    Messages:
    494
    Likes Received:
    382
    Reputations:
    22
    Удалите этот треш ...