Показать сообщение отдельно

  #5  
Старый 13.08.2008, 01:09
luz3r
Banned
Регистрация: 23.02.2008
Сообщений: 268
Провел на форуме:
3103600

Репутация: 850
Post

Ассембли. Урок 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. Посмотрим на следующий код:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.code

start:

invoke MessageBox,0,'привет!','заголовок', MB_OK ; вызываем окошко
invoke ExitProcess,0 ; завершаем процесс

.end start
Посмотрите стиль окошка - MB_OK, соответственно окошко выскочит с одной кнопкой OK. И если мы нажмём OK то функция возвратит IDOK. Но что если нам

нужно например использовать две кнопки, например OK & CANCEL. Для этого есть специальный стиль окна - MB_OKCANCEL. Вообще они конечно описаны в MSDN,

так что я не буду их приводить в этом тексте. Пример:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.code

start:

invoke MessageBox,0,'привет!','заголовок', MB_OKCANCEL ; вызываем окошко
invoke ExitProcess,0 ; завершаем процесс

.end start
Тогда, соответственно при выполнении этого кода, если мы нажали на OK, функция возвратит IDOK, если CANCEL - то получим IDCANCEL. Чтобы узнать что

возвращает та или иная функция - обратитесь к MSDN (для этого знание технического английского вам поможет). Кстати функции возвращают значения через

регистр EAX почти всегда. Так что, чтобы проверить возвращаемое значение - нужно проверить именно регистр EAX. Давайте сделаем проверку, при которой

если мы нажимаем например на OK выскакивает окошко и говорит нам что мы нажали именно эту кнопку, если CANCEL - то соответственно сообщение будет

другим:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.code

start:

invoke MessageBox,0,'привет!','заголовок', MB_OKCANCEL ; вызываем окошко
cmp eax,IDOK ; проверяем что нажали ok
jz OK_PRESSED ; если да - прыгаем на соответствующее сообщение
invoke MessageBox,0,'вы нажали CANCEL','заголовок',MB_OK ; если нет - то не прыгаем и выводим что нажали CANCEL
jmp EXIT ; прыгаем на выход чтобы избежать появления второго окна

OK_PRESSED:

invoke MessageBox,0,'вы нажали OK','заголовок',MB_OK ; выводим сообщение про OK
EXIT:

invoke ExitProcess,0 ; завершаем процесс

.end start
Надеюсь из комментариев всё ясно, но на всякий случай поясню, что после того как мы вивели окно с приветствием, мы проверяем с помощью оператора CMP,

значение регистра EAX и если там IDOK то прыгаем на сообщение и говорим что нажали OK, иначе выводим сообщение что нажали CANCEL и прыгаем на метку

EXIT дабы избежать появления второго окна, ведь код продолжит выполняться и наткнёться на строку invoke MessageBox,0,'вы нажали OK','заголовок',MB_OK

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

Теперь займёмся переменными:

Переменные должны быть обьявлены в секции данных - .data . Сначала мы пишем имя переменной потом через пробел - её размер, и только потом через пробел

её значение. Пример:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.data

perem1 dd 0

.code

start:

invoke ExitProcess,0

.end start
В этом примере мы обьявили переменную perem1 размером в 4 байта (dd - define dword (двойное слово - 4 байта)) и присвоили ей значение 0 (нуль). Теперь

в неё можно писать данные, но не более 4 байт, так как мы задали размер именно в 4 байта. Можно считывать значение переменной итд. Кстати, для того

чтобы считать значение переменной, её нужно обрамить скобками вот так:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.data

perem1 dd 0

.code

start:

mov eax,[perem1]
invoke ExitProcess,0

.end start
Но чтобы считать её адрес в памяти - обрамление скобками не требуеться. Пример:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.data

perem1 dd 0

.code

start:

mov eax,perem1
invoke ExitProcess,0

.end start
Давайте теперь примерим всё это на практике. Напимеш программу для вывода текста в окно при помощи переменных. Для этого рассмотрим параметры самой

функции, которые кстати вы можете и сами посмотреть в 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
);

Из этого ясно что: Для текста в заголовке и для текста в окне, мы должны передавать не значения, а адреса переменных, которые этот текст содержат.

Сделаем это:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.data

text db "наш текст",00h
zagolovok db "заголовок",00h

.code

start:

invoke MessageBox,0,text,zagolovok,0
invoke ExitProcess,0

.end start
Обратите внимание как мы обьявляем строки - как массив байтов, которые заканчиваються нулевым байтом. Кстати db - это обьявить байт. Заметьте также,

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



-------------------------------------------------------------------
Вроде всё доходчиво описано... поймёт каждый. =)

Последний раз редактировалось luz3r; 13.08.2008 в 01:18..
 
Ответить с цитированием