стрельба по-македонски ДМИТРИЙ КОВАЛЕНКО Спецвыпуск: Хакер, номер #071, стр. 071-040-1 ПРОГРАММИРОВАНИЕ НА НЕСКОЛЬКИХ ЯЗЫКАХ ПОД ПРОГРАММИРОВАНИЕМ НА НЕСКОЛЬКИХ ЯЗЫКАХ МЫ БУДЕМ ПОНИМАТЬ РАЗРАБОТКУ ОДНОЙ ПРОГРАММЫ С ИСПОЛЬЗОВАНИЕМ НЕСКОЛЬКИХ ЯЗЫКОВ И ВЗАИМОДЕЙСТВИЕ ПРОГРАММ, НАПИСАННЫХ НА РАЗНЫХ ЯЗЫКАХ В программах на Visual C++ и Delphi можно делать ассемблерные вставки. Это называется inline-ассемблером. Обычно inline-ассемблер используется в двух случаях: 1 ЕСЛИ НУЖНО ОПТИМИЗИРОВАТЬ КРИТИЧНЫЕ ПО СКОРОСТИ И НЕБОЛЬШИЕ ПО ОБЪЕМУ УЧАСТКИ ПРОГРАММЫ. ГРАМОТНО НАПИСАННЫЙ АССЕМБЛЕРНЫЙ КОД ВСЕГДА БЫСТРЕЕ КОДА, КОТОРЫЙ ГЕНЕРИРУЕТСЯ КОМПИЛЯТОРОМ C++ ИЛИ DELPHI. 2 НУЖЕН ПРЯМОЙ ДОСТУП К ПАМЯТИ И ПОРТАМ. ЧАЩЕ ВСЕГО ИСПОЛЬЗУЕТСЯ В ДРАЙВЕРАХ, ТАК КАК ИЗ ТРЕТЬЕГО КОЛЬЦА ЗАЩИТЫ С ПОРТАМИ НЕ ОЧЕНЬ-ТО ПОРАБОТАЕШЬ. Поскольку информации об inline-ассемблерах в интернете довольно мало, мы остановимся на этом подробнее. [Inline-ассемблер в Visual C++.] Ассемблерные вставки в исходниках Visual C++ оформляются с помощью блока __asm и выглядят примерно так: // обычный код на C++ printf("Hello!\n"); // а тут ассемблерная вставка __asm { mov eax, 2 mov edx, 7 add eax, edx } // а потом снова обычный код на C++ printf("Bye!"); Или, что то же самое, так: // ассемблерная вставка __asm mov eax, 2 __asm mov edx, 7 __asm add eax, edx А можно вообще в одну строчку: // ассемблерная вставка __asm mov eax, 2 __asm mov edx, 7 __asm add eax, edx В inline-ассемблере Visual C++ можно использовать все инструкции вплоть до Pentium 4 и AMD Athlon. Поддерживается также MMX. Поддержки Itanium и x64 пока нет :(. По синтаксису inline-ассемблер Visual C++ частично совпадает с MASM. Например, как и в MASM можно строить выражения с операндами и использовать offset с глобальными переменными (смотри листинг 1). Как и в MASM, можно использовать глобальные метки и принудительно определять короткие переходы (смотри листинг 2). Однако определить локальную метку с помощью @@ в inline-ассемблере Visual C++ не получится – замена lab: на @@lab: в предыдущем примере вызовет ошибку компиляции. Есть и другие отличия от MASM. Например, в inline-ассемблере Visual C++ нет никаких средств для объявления переменных, поэтому про привычные DB, DW, DD, DQ, DT, DF, DUP и THIS можно забыть. Зато можно использовать переменные, объявленные в программе на C++ (смотри листинг 3). В inline-ассемблере также нельзя объявлять структуры — директивы STRUC, RECORD, WIDTH и MASK недопустимы. Вместо этого можно использовать структуры, объявленные в программе на C++ (смотри листинг 4). Кроме того, в inline-ассемблере можно использовать комментарии и HEX-числа в стиле C++. В принципе, все отличия подробно описаны в MSDN 2006 (идет в комплекте с Visual Studio 2006). Обычно в Visual C++ inline-ассемблер используется для написания функций. Как правило, функции, написанные на inline-ассемблере, объявляют с использованием директивы _stdcall. В этом случае параметры передаются в функцию на стеке в обратном порядке, а результат работы возвращается в eax. Для примера рассмотрим функцию, которая находит длину ASCIIZ-строки: int _stdcall get_str_length(char *inputstr) |