стрельба по-македонски ДМИТРИЙ КОВАЛЕНКО Спецвыпуск: Хакер, номер #071, стр. 071-040-2 { // чаще всего функция целиком состоит из одной // большой ассемблерной вставки __asm{ ; можно свободно обращаться к переменным, ; переданным в функцию mov edi, inputstr mov esi, edi mov ecx, -1 xor al, al cld repne scasb sub edi, esi ; результат работы функции следует ; возвращать в eax mov eax, edi dec eax } } Использовать эту функцию можно так: int main() { char str_1[]="Hello, world!"; int i; i = get_str_length(str_1); printf("String: %s\nLength: %d", str_1, i); } При написании кода на inline-ассемблере Visual C++ следует помнить некоторые моменты. Во-первых, значения регистров не передаются между ассемблерными вставками. Например, если в ассемблерной вставке ты установил eax в 1, то в следующей ассемблерной вставке eax не обязательно будет равно 1 (смотри листинг 5). Во-вторых, нужно быть осторожным с регистрами и стеком. В середине ассемблерных вставок нельзя менять регистры ds, ss, sp, bp и флаги. Если эти регистры все-таки меняются, перед выходом из ассемблерной вставки их нужно обязательно восстановить. Что касается стека, то тут нужно соблюдать правило, которое гласит: если в ассемблерной вставке нечто ложится на стек, то в той же ассемблерной вставке это «нечто» должно со стека сниматься. Рассмотрим, например, такой код: #include <stdio.h> // наша функция на ассемблере void _stdcall Test() { __asm{ ; кладем на стек eax push eax ; перед тем как ассемблерная вставка кончится, нужно ; снять eax со стека (например, с помощью pop), ; но мы забыли это сделать ;) } } int main() { // вызываем функцию... и любуемся сообщением об ошибке :) Test(); } И, наконец, если ты пишешь не драйвер, а обычное Win32-приложение, в ассемблерной вставке не должно быть привилегированных инструкций. Вот, пожалуй, и все про inline-ассемблер Visual C++. Тем, кто хочет узнать больше, советуем почитать MSDN 2006 – там есть вся необходимая информация. [Inline-ассемблер в Delphi] во многом похож на inline-ассемблер Visual C++. Поэтому, чтобы не повторяться, мы рассмотрим некоторые моменты вобщем, без подробностей. Ассемблерные вставки в Delphi размещаются между asm и end, например: {обычный код на Pascal} Writeln('Hello!'); {вставка на ассемблере} asm mov al,1 mov bx,2 end; {и снова обычный код на Pascal} Writeln('Bye!'); Inline-ассемблер Delphi поддерживает все инструкции вплоть до Pentium 4 и AMD Athlon. Также можно использовать инструкции AMD 3DNow! для AMD K6 и AMD Enhanced 3DNow! для AMD Athlon. К сожалению, поддержки 64-разрядного кода нет, так что про Itanium и x64 можно забыть. По синтаксису inline-ассемблер Delphi в основном похож на MASM. Например, поддерживаются выражения MASM и локальные метки. Также разрешено использование offset для глобальных переменных, объявленных в программе (смотри листинг 6). Как и в MASM, можно использовать глобальные метки, но они должны быть объявлены в секции label (смотри листинг 7). Есть и отличия от MASM. К примеру, комментарии в ассемблерных вставках должны быть обязательно в стиле Delphi, в операторах безусловного перехода нельзя использовать short и т.п. Все эти отличия описаны в документации, которая идет с Borland Developer Studio (файл Reference.pdf). |