64-битный привет Крис Касперски ака мыщъх Хакер, номер #083, стр. 083-118-6 Ниже идет пример простейшей x86-64 программы, которая не делает ничего, только возвращает в регистре RAX значение 0. ; сообщаем FASM'у, что мы хотим программировать на x86-64 use64 xor r9,r9 ; обнуляем регистр r9 mov rax,r9 ; пересылаем в rax,r9 (можно сразу mov rax,0, но неинтересно) ret ; выходим туда откуда пришли Никаких дополнительных аргументов командной строки указывать не надо, просто сказать fasm file-name.asm и все! Через мгновение образуется файл file-name.bin, который в hex-представлении выглядит следующим образом: [дизассемблерный листинг простейшей 64-битной программы] 4D 31 C9 xor r9, r9 4C 89 C8 mov rax, r9 C3 retn Формально, это типичный com-файл, вот только запустить его не удастся (во всяком случае, ни одна популярная ось его не съест) и необходимо замутить законченный ELF или PE, в заголовке которого будет явно прописана нужная разрядность. Начиная с версии 1.64, ассемблер FASM поддерживает специальную директиву format PE64", автоматически формирующую 64-разрядный PE-файл (директиву use64 в этом случае указывать уже не нужно), а в каталоге EXAMPLES можно найти готовый пример PE64DEMO, в котором показано, как ее использовать на практике. Ниже приведен пример x86-64 программы hello, world" с комментариями: [64-битное приложение "hello, world" под Windows на FASM'е] ; пример 64-битного PE файла ; для его выполнения необходимо иметь Windows XP 64-bit edition ; указываем формат format PE64 GUI ; указываем точку входа entry start ; создать кодовую секцию с атрибутами на чтение и исполнение section '.code' code readable executable start: mov r9d,0 ; uType == MB_OK (кнопка по умолчанию) ; аргументы по соглашению x86-64 ; передаются через регистры, не через стек! ; префикс d задает регистр размером в слово, ; можно использовать и mov r9,0, но тогда ; машинный код будет на байт длиннее lea r8,[_caption] ; lpCaption передаем смещение ; команда lea занимает всего 7 байт, ; а mov reg, offset - целых 11, так что ; lea намного более предпочтительна lea rdx,[_message] ; lpText передаем смещение выводимой строки mov rcx,0 ; hWnd передам дескриптор окна владельца ; (можно также использовать xor rcx, rcx, ; что на три байта короче) call [MessageBox] ; вызываем функцию MessageBox mov ecx,eax ; заносим в ecx результат возврата ; (Функция ExitProcess ожидает 32-битный параметр ; можно использовать и mov rcx, rax, но это будет ; на байт длиннее) call [ExitProcess] ; вызываем функцию ExitProcess ; создать секцию данных с атрибутами на чтение и запись ; (вообще-то в данном случае атрибут на запись необязателен, ; поскольку мы ничего не пишем, а только читаем) section '.data' data readable writeable _caption db 'PENUMBRA is awesome!',0 ; ASCIIZ-строка заголовка окна _message db 'Hello World!',0 ; ASCIIZ-строка выводимая на экран ; создать секцию импорта с атрибутами на чтение и запись ; (здесь атрибут на запись обязателен, поскольку при загрузке PE-Файла ; в секцию импорта ; будут записываться фактические адреса API-функций) |