Fasm ассемблер: MASM, TASM, FASM, NASM под Windows и Linux / Хабр
Содержание
MASM, TASM, FASM, NASM под Windows и Linux / Хабр
Часть I
Часть II
Часть III
В данной статье я хочу рассмотреть вопросы, которые могут возникнуть у человека, приступившего к изучению ассемблера, связанные с установкой различных трансляторов и трансляцией программ под Windows и Linux, а также указать ссылки на ресурсы и книги, посвященные изучению данной темы.
MASM
Используется для создания драйверов под Windows.
По ссылке переходим на сайт и скачиваем пакет (masm32v11r.zip). После инсталляции программы на диске создается папка с нашим пакетом C:\masm32. Создадим программу prog11.asm, которая ничего не делает.
.586P
.model flat, stdcall
_data segment
_data ends
_text segment
start:
ret
_text ends
end start
Произведём ассемблирование (трансляцию) файла prog11.asm, используя ассемблер с сайта masm32.
Ключ /coff используется здесь для трансляции 32-битных программ.
Линковка производится командой link /subsystem:windows prog11.obj (link /subsystem:console prog11.obj)
Как сказано в Википедии
MASM — один из немногих инструментов разработки Microsoft, для которых не было отдельных 16- и 32-битных версий.
Также ассемблер версии 6. можно взять на сайте Кипа Ирвина kipirvine.com/asm, автора книги «Язык ассемблера для процессоров Intel».
Кстати, вот ссылка на личный сайт Владислава Пирогова, автора книги “Ассемблер для Windows”.
MASM с сайта Microsoft
Далее скачаем MASM (версия 8.0) с сайта Microsoft по ссылке. Загруженный файл носит название «MASMsetup.exe». При запуске этого файла получаем сообщение -«Microsoft Visual C++ Express Edition 2005 required».
Открываем этот файл архиватором (например 7zip). Внутри видим файл setup.exe, извлекаем его, открываем архиватором. Внутри видим два файла vc_masm.msi,vc_masm1.cab. Извлекаем файл vc_masm1.cab, открываем архиватором. Внутри видим файл FL_ml_exe_____X86.3643236F_FC70_11D3_A536_0090278A1BB8. Переименовываем его в файл fl_ml.exe, далее, произведём ассемблирование файла prog11.asm, используя ассемблер fl_ml.exe.
MASM в Visual Studio
Также MASM можно найти в папке с Visual Studio (у меня VS 10) вот здесь: C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\ml.exe.
Для того, чтобы запустить на 32- или 64-разрядной системе и создавать программы, работающие как под 32-, так и под 64-разрядной Windows, подходит MASM32 (ml.exe, fl_ml.exe). Для того, чтобы работать на 32- и 64-разрядных системах и создавать программы, работающие под 64-разрядной Windows, но неработающие под 32-разрядной нужен ассемблер ml64.exe. Лежит в папке C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64 и вот здесь — C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64.
TASM
Программный пакет компании Borland, предназначенный для разработки программ на языке ассемблера для архитектуры x86. В настоящее время Borland прекратила распространение своего ассемблера.
Скачать можно, например, здесь. Инсталлятора нет, просто извлекаем программу. Вот исходник из книги Питера Абеля (рис. 3.2) «Язык Ассемблера для IBM PC и программирования».
stacksg segment para stack 'stack'
db 12 dup ('stackseg')
stacksg ends
codesg segment para 'code'
begin proc far
assume ss:stacksg,cs:codesg,ds:nothing
push ds
sub ax,ax
push ax
mov ax, 0123h
add ax, 0025h
mov bx,ax
add bx,ax
mov cx,bx
sub cx,ax
sub ax,ax
nop
ret
begin endp
codesg ends
end begin
Выполним ассемблирование (трансляцию) файла abel32.asm.
Корректность работы программы можно проверить, произведя линковку (tlink.exe) объектного файла и запустив полученный файл в отладчике.
Как было сказано выше, MASM можно использовать для работы с 16-битными программами. Выполним ассемблирование (трансляцию) программы abel32.asm с помощью ассемблера MASM:
Ключ /coff здесь не используется.
Линковка производится файлом link16.exe
FASM
В статье Криса Касперски «Сравнение ассемблерных трансляторов» написано, что «FASM — неординарный и весьма самобытный, но увы, игрушечный ассемблер. Пригоден для мелких задач типа „hello, world“, вирусов, демок и прочих произведений хакерского творчества.»
Скачаем FASM с официального сайта. Инсталлятора нет, просто извлекаем программу. Откроем fasm editor — C:\fasm\fasmw.exe. В папке C:\fasm\EXAMPLES\HELLO есть файл HELLO.asm.
include 'win32ax.inc'
.code
start:
invoke MessageBox,HWND_DESKTOP,"Hi! I'm the example program!",invoke GetCommandLine,MB_OK
invoke ExitProcess,0
.end start
Откроем файл HELLO.asm из fasmw.exe. Изменим строку include ‘win32ax.inc’ на строку include ‘c:\fasm\INCLUDE\WIN32AX.INC’. Запускаем из меню Run → Run.
Вот ссылки на ресурсы, посвященные FASM:
→ FASM на Cyberforum’е
→ FASM на asmworld .com программы под Dos
→ Цикл статей «Ассемблер под Windows для чайников»
→ Сайт на narod’е
FASM в Linux
Для того, использовать FASM в Linux (у меня Ubuntu), скачаем соответствующий дистрибутив (fasm-1.71.60.tgz), распакуем его, в папке у нас будет бинарный файл fasm, копируем этот файл в /usr/local/bin для того, чтобы можно было запускать его из консоли, как любую другую команду.Выполним ассемблирование программы hello.asm из папки fasm/examples/elfexe/hello.asm.
Корректность работы программы можно проверить в отладчике.
Nasm
Nasm успешно конкурирует со стандартным в Linux- и многих других UNIX-системах ассемблером Gas.
Nasm в Linux можно установить его с помощью менеджера пакетов или из командной строки: в дистрибутиве Debian (Ubuntu) командой apt-get install nasm, в дистрибутивах Fedora, CentOS, RedHat командой yum install nasm.
Создадим программу, которая 5 раз выводит сообщение “Hello”. Пример взят из книги Андрея Викторовича Столярова “Программирование на языке ассемблера NASM для ОС UNIX”. Учебник, а также библиотека “stud_io.inc” есть на личном сайте автора.
%include "stud_io.inc"
global _start
section .text
_start: mov eax, 0
again: PRINT "Hello"
PUTCHAR 10
inc eax
cmp eax, 5
jl again
FINISH
Выполним ассемблирование и линковку и запустим файл hello.asm.
$ nasm -f elf hello.asm
$ ld hello.o -o hello
$ ./hello
Для 64bit необходимо использовать команду nasm -f elf64 hello.asm
NASM для Windows
NASM для Windows можно установить, скачав соответствующий дистрибутив с соответствующего сайта.
Ассемблирование:nasm -f bin имя_файла.asm -o имя_файла.com
Ссылки на ресурсы, посвященные Nasm:
→ Сайт А.В. Столярова
→ Сайт, на котором лежит электронный учебник (в архиве)
→ То же самое
AS
Стандартный ассемблер практически во всех разновидностях UNIX, в том числе Linux и BSD. Свободная версия этого ассемблера называется GAS (GNU assembler). Позволяет транслировать программы с помощью компилятора GCC.
Из учебников удалось найти только книгу на английском «Programming from the ground up». На русском удалось найти только одну главу из книги С. Зубкова «Assembler для DOS, Windows и UNIX».
Возьмем пример программы, которая ничего не делает, с сайта. Создадим программу gas.s
.section .text
.globl _start
_start:
movl $1, %eax
movl $2, %ebx
int $0x80
Выполним ассемблирование (трансляцию), линковку и запуск программы:
$ as -o gas.o gas.s
$ ld -o gas gas.o
$ ./gas
Если в данной программе изменить _start на main, то можно выполнить ассемблирование (трансляцию) и линковку компилятором gcc.
.section .text
.globl main
main:
movl $1, %eax
movl $2, %ebx
int $0x80
Выполним ассемблирование (трансляцию), линковку и запуск программы:
$ gcc gas.s -o gas
$ ./gas
Выводы: если вы изучаете программирование под Windows, то вы можете остановить свой выбор на Masm; Tasm больше не поддерживается, но для обучения по старым классическим учебникам подойдёт.
Под Linux Gas подойдет тем, кто использует GCC, а тем, кому не нравится синтаксис Gas, подойдёт Nasm.
P.S. Следующие две части, в целом, посвящены обработке строки в цикле.
P.P.S. Little Man Computer — учебная модель компьютера с ограниченым набором ассемблерных инструкций рассматривается в этой статье.
Програмирование на fasm под Win64 часть 1 \»Ассемблер, отладчик, IDE\»
Введение
Я начинаю цикл статей по ассемблеру fasm. Возможно у вас есть вопрос: “Зачем в 21 веке нужен ассемблер?”. Я бы ответил так: Конечно, знание ассемблера не обязятельно, но оно способствует пониманию, во что превращается ваш код, как он работает, это позволяет почувствовать силу. Ну и в конце концов: Писать на ассемблере просто приятно (ну по крайней мере небольшие приложения).
Так что надеюсь, что мои статьи будут вам полезны.
Где взять fasm?
Собственно тут: http://flatassembler.net/download.php
На этой странице Томаш Грыштар(создатель fasm-а) выкладывает последнюю версию ассемблера. Там есть версии для DOS, Linux, Unix и Windows, нам нужна для Windows. В скачанном архиве находятся следующие компоненты:
- fasm.exe – собственно сам ассемблер
- fasmw.exe – IDE (среда разработки)
- fasm.pdf – документация
- папка source – исходники fasm-а (написан на самом себе)
- папка include – папка с заголовками, импортами, и т.д.
- папка examples – примеры программ на fasm-е
Содержимое fasm.pdf дублирует 2 раздела документации “flat assembler 1.71 Programmer’s Manual” и “Windows programming” отсюда: http://flatassembler.net/docs.php
IDE (среда разработки)
Перед тем, как писать программы нужно определиться, в чём их писать. Для fasm-а существуют разные IDE, например: fasmw.exe(находится в архиве с fasm-ом), RadAsm, WinAsm Studio, Fresh, … Выберайте, какая вам больше по вкусу. Сразу скажу, что IDE из поставки fasm-а обладает минимальным количеством фичей, так что я бы рекомендовал использовать альтернативную IDE. Я, например, использую RadAsm 3.0, его можно взять здесь: https://fbedit.svn.sourceforge.net/svnroot/fbedit/RadASM30/Release/RadASM.zip (это хорошая IDE, но к сожалений она больше не обновляется) К статье приложен файл Fasm.ini, там выбрана чёрная тема, добавлены x64 регистры и добавлена подсветка для большего числа инструкций. Можете поставить его вместо Fasm.ini поумолчанию, только исправьте в нём пути к папке с fasm-ом в 6 и 7 строках. Там написано:
Код (Text):
[Environment]
0=path,C:\Program Files (x86)\fasm;$A\..\Ollydbg
1=include,C:\Program Files (x86)\fasm\INCLUDE
Если вы распаковали fasm в папку <полный путь>, то надо заменить приведённый выше код на:
Код (Text):
[Environment]
0=path,<полный путь>\fasm;$A\..\Ollydbg
1=include,<полный путь>\fasm\INCLUDE
Отладчик
Писать программы это — хорошо, но нужно находить и исправлять баги, для этого нужен отладчик. Существуют разные отладчики способные отлаживать 64-битный код например: WinDbg, fdbg, x64dbg. Наиболее удобный на мой взгляд — x64dbg, его можно скачать здесь.
Это — всё, что я хотел рассказать в первой части.
|
|
Линия FASM Ассемблер в окне
То что вы нашли — это примеры для dos, под windows они совершенно не применимы (к тому же вообще не относится к рисованию чего-либо).
Для рисования в окне сначала нужно создать это окно. Чтобы увидеть как это делается — идем в папку примеров fasm, смотрим шаблон оконного приложения (у меня это c:\fasm\EXAMPLES\TEMPLATE\TEMPLATE.ASM
). Пример на 75 строк — это все только для создания окна и базовой обработки сообщений окна (хотя за счет использования win32wx.inc
вместо win32w.inc
можно было избавиться от явного создания секции импортов). Т.е. просто вызовом какой-нибудь одной функции дело не закончится. К слову, на С/С++ просто создание окна с использованием WinAPI займет примерно столько же строк.
Тут возможно стоит остановиться и задуматься, действительно ли вы хотите рисовать средствами WinAPI, еще и на ассемблере?
Код примера (без рисования) ниже:
; Template for program using standard Win32 headers
format PE GUI 4.0
entry start
include 'win32w.inc'
section '.text' code readable executable
start:
invoke GetModuleHandle,0
mov [wc.hInstance],eax
invoke LoadIcon,0,IDI_APPLICATION
mov [wc.hIcon],eax
invoke LoadCursor,0,IDC_ARROW
mov [wc.hCursor],eax
invoke CreateSolidBrush, 0x00FF00
mov [wc.hbrBackground], eax
invoke RegisterClass,wc
test eax,eax
jz error
invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,128,128,256,192,NULL,NULL,[wc.hInstance],NULL
test eax,eax
jz error
; invoke ShowWindow,eax,SW_SHOWNORMAL
msg_loop:
invoke GetMessage,msg,NULL,0,0
cmp eax,1
jb end_loop
jne msg_loop
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp msg_loop
error:
invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK
end_loop:
invoke ExitProcess,[msg.wParam]
proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
cmp [wmsg],WM_DESTROY
je .wmdestroy
.defwndproc:
invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
jmp .finish
.wmdestroy:
invoke PostQuitMessage,0
xor eax,eax
.finish:
ret
endp
section '.data' data readable writeable
_class TCHAR 'FASMWIN32',0
_title TCHAR 'Win32 program template',0
_error TCHAR 'Startup failed.',0
wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BACKGROUND,NULL,_class
msg MSG
section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL',\
gdi32,'GDI32.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
include 'api\gdi32.inc'
Дальше, для рисования линии вам нужны функции MoveToEx
и LineTo
, и воткнуть их вызов нужно не где-попало, а конкретно внутри процедуры обработки сообщений окна (в примере выше — WindowProc
).
Просто чтобы рисовать линию при каждой перерисовке окна, нужно добавить обработку сообщения WM_PAINT
в WindowProc
:
proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
cmp [wmsg], WM_DESTROY
je .wmdestroy
cmp [wmsg], WM_PAINT
je .wmpaint
.defwndproc:
invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
jmp .finish
.wmdestroy:
invoke PostQuitMessage,0
xor eax,eax
jmp .finish
.wmpaint:
invoke BeginPaint, [hwnd], paintstruct ; получаем контекст окна
mov [hdc], eax ; сохраняем контекст окна в переменную
invoke MoveToEx, [hdc], 10, 15, 0 ; 10, 15 - начальные координаты
invoke LineTo, [hdc], 200, 100 ; 200, 100 - конечные координаты
invoke EndPaint, [hwnd], paintstruct ; освобождаем контекст окна
.finish:
ret
endp
Полный код с рисованием:
format PE GUI 4.0
include 'win32wx.inc'
.data
_class TCHAR 'FASMWIN32',0
_title TCHAR 'Win32 program template',0
_error TCHAR 'Startup failed.',0
wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BACKGROUND,NULL,_class
msg MSG
hdc dd ?
paintstruct PAINTSTRUCT
.code
start:
invoke GetModuleHandle,0
mov [wc.hInstance],eax
invoke LoadIcon,0,IDI_APPLICATION
mov [wc.hIcon],eax
invoke LoadCursor,0,IDC_ARROW
mov [wc.hCursor],eax
invoke CreateSolidBrush, 0xFFFFFF ; белый фон
mov [wc.hbrBackground], eax
invoke RegisterClass,wc
test eax,eax
jz error
invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,128,128,256,192,NULL,NULL,[wc.hInstance],NULL
test eax,eax
jz error
; invoke ShowWindow,eax,SW_SHOWNORMAL
msg_loop:
invoke GetMessage,msg,NULL,0,0
cmp eax,1
jb end_loop
jne msg_loop
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp msg_loop
error:
invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK
end_loop:
invoke ExitProcess,[msg.wParam]
proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
cmp [wmsg], WM_DESTROY
je .wmdestroy
cmp [wmsg], WM_PAINT
je .wmpaint
.defwndproc:
invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
jmp .finish
.wmdestroy:
invoke PostQuitMessage,0
xor eax,eax
jmp .finish
.wmpaint:
invoke BeginPaint, [hwnd], paintstruct ; получаем контекст окна
mov [hdc], eax ; сохраняем контекст окна в переменную
invoke MoveToEx, [hdc], 10, 15, 0 ; 10, 15 - начальные координаты
invoke LineTo, [hdc], 200, 100 ; 200, 100 - конечные координаты
invoke EndPaint, [hwnd], paintstruct ; освобождаем контекст окна
.finish:
ret
endp
.end start
Что это такое Ассемблер fasm. Энциклопедия
Пользователи также искали:
fasm,
ассемблеру,
ассемблеры,
assemblers,
ассемблере,
ассемблер,
assembler,
hello world,
уроки,
masm,
world,
hello,
ассемблера,
tasm,
asmworld,
примеры,
учебный,
курс,
часть,
необходимые,
инструменты,
учебник,
начинающих,
hello world assembler,
что можно написать на ассемблере,
ассемблер для начинающих примеры,
fasm hello world,
ассемблер уроки,
fasm уроки,
ассемблере assembler,
Ассемблер FASM под Windows: ищу исходники примеров. Подскажите интересную литературу по языку flat asm, ответ желательно писать так автор:название.. .. Обучающие видео по Flat Assembler FASM с нуля Courses R0. Если вы новичок, читайте учебники по программированию на ассемблере. Flat assembler по умолчанию. .. 8. FASM подробно: Hello, world! 4. Введение в ассемблер. Microsoft Macro Assembler. Версии ассемблеров. MASM ассемблер для процессоров семейства x86. Первоначально был. .. Учебный курс. Часть 1. Необходимые инструменты Asmworld. Самый простой способ использовать функции C. В своем простейшем использовании printf берет строку в качестве параметра и. .. Новые вопросы с меткой Stack Overflow на русском. Введение Я начинаю цикл статей по ассемблеру fasm. Возможно у вас есть вопрос: Зачем в 21 веке нужен ассемблер?. Я бы ответил.. .. статья Ассемблер в Unix assembler linux freebsd OpenNET. Подскажите что я нетак изменил в коде. И если не сложно покажите пример простого консольного приложения на asm под x64. Вот код:. .. Программирование на языке Assembler в FASM. Откроем файл -. из google-wiki.info. Изменим строку win32ax. на строку include c:fasmINCLUDEWIN32AX.INC.. .. Какая есть литература по fasm? google-wiki.info. В моем учебном курсе я буду использовать FASM. Это довольно новый, удобный, быстро развивающийся компилятор ассемблера,. .. fasm основное руководство. Чтобы увидеть как это делается идем в папку примеров fasm, смотрим у меня это c:fasmEXAMPLESTEMPLAgoogle-wiki.info.. .. Оконное приложение на ассемблере Блог по Windows. Введение. В начале было слово Если точнее то было просто предложение от Kinder а написать статью посвящённую макросам в FASM. Я согласился. |
MASM, TASM, FASM, NASM под Windows и Linux Хабр. Будут рассмотрены основные базовые директивы ассемблера FASM, которые позволяют существенно влиять на структуру. .. Flat assembler FASM. Ассемблер транслятор исходного кода на языке ассемблера в машинный код. Flat Assembler, или FASM, является многопроходным. .. Установка и настройка Flat Assembler FASM Образ мышления. Flat Assember fasm свободно распространяемый ассемблер, написанный Tomasz Grysztar. Поддерживает вариант синтаксиса Intel, не совместимый. .. Програмирование на fasm под Win64 часть 1 Ассемблер. Для UNIX систем есть два основных ассемблера это NASM Netwide и FASM Flat Assembler. Для линейки Windows. .. Fasm, Hello World x64 компилится но не работает Assembler. Если у вас этого нет, то ни один, даже самый последний RedHat на пару со свежим fasmом вам не поможет. И еще, о компиляторах в unix обычно. .. Погружение в assembler. Полный курс по программированию на. Решено: Ассемблер FASM под Windows: ищу исходники примеров Assembler Ответ.. .. Написать две программы на Ассемблере fasm Заказы. 25 апр 2008 FASM новый ассемблер, более удобный синтаксис, поддерживает очень большой набор инструкций, компилирует сразу в нужный. .. Обьясните различия между FASM, WASM, VASM, MASM, TASM. 30 ноября 2018, 18:11 2 отклика 50 просмотров. ассемблер fasm. 1 Разработать программу определения количества обобщённых чисел Ферма. .. Линия FASM Ассемблер в окне Stack Overflow на русском. 1 ноя 2008 Программирование на Ассемблере я начинал с Turbo TASM под MS DOS, сейчас пишу на Flat Assembler FASM под. .. Как писать на консоль в fasm? assembly Qaru. Пишем программу на Flat assembler для Windows DOS эмулятор, командная строка на примере Hello, world! Все разбираем очень. |
Написание и отладка кода на ассемблере x86/x64 в Linux
Сегодня мы поговорим о программировании на ассемблере. Вопрос «зачем кому-то в третьем тысячелетии может прийти в голову писать что-то на ассемблере» раскрыт в заметке Зачем нужно знать всякие низкоуровневые вещи, поэтому здесь мы к нему возвращаться не будем. Отмечу, что в рамках поста мы сосредоточимся на вопросе компиляции и отладки программ на ассемблере. Сам же язык ассемблера заслуживает отдельного большого поста, а то и серии постов.
Если вы знаете ассемблер, то любая программа для вас — open source.
Народная мудрость.
Введение
Существует два широко используемых ассемблерных синтаксиса — так называемые AT&T-синтаксис и Intel-синтаксис. Они не сильно друг от друга отличаются и легко переводятся один в другой. В мире Windows принято использовать синтаксис Intel. В мире *nix систем, наоборот, практически всегда используется синтаксис AT&T, а синтаксис Intel встречается крайне редко (например, он используется в утилите perf). Поскольку Windows, как известно, не существует, далее мы сосредоточимся на правильном AT&T-синтаксисе 🙂
Компиляторов ассемблера существует много. Мы будем использовать GNU Assembler (он же GAS, он же /usr/bin/as). Скорее всего, он уже есть вашей системе. К тому же, если вы пользуетесь GCC и собираетесь писать ассемблерные вставки в коде на C, то именно с этим ассемблером вам предстоит работать. Из достойных альтернатив GAS можно отметить NASM и FASM.
Наконец, язык ассемблера отличается в зависимости от архитектуры процессора. Пока что мы сосредоточимся на ассемблере для x86 (он же i386) и x64 (он же amd64), так как именно с этими архитектурами приходится чаще всего иметь дело. Впрочем, ARM тоже весьма распространен, главным образом на телефонах и планшетах. Еще из сравнительно популярного есть SPARC и PowerPC, но шансы столкнуться с ними весьма малы. Отмечу, что x86 и x64 можно было бы рассматривать отдельно, но эти архитектуры во многом похожи, поэтому я не вижу в этом большого смысла.
«Hello, world» на int 0
x80
Рассмотрим типичный «Hello, world» для архитектуры x86 и Linux:
.data
msg:
.ascii «Hello, world!\n»
.set len, . — msg
.text
.globl _start
_start:
# write
mov $4, %eax
mov $1, %ebx
mov $msg, %ecx
mov $len, %edx
int $0x80
# exit
mov $1, %eax
xor %ebx, %ebx
int $0x80
Компиляция:
# Или: gcc -m32 -c hello-int80.s
as —32 hello-int80.s -o hello-int80.o
ld -melf_i386 -s hello-int80.o -o hello-int80
Коротко рассмотрим первые несколько действий, выполняемых программой: (1) программа начинает выполнение с метки _start, (2) в регистр eax кладется значение 4, (3) в регистр ebx помещается значение 1, (4) в регистр ecx кладется адрес строки, (5) в регистр edx кладется ее длина, (6) происходит прерывание 0x80. Так в мире Linux традиционно происходит выполнение системных вызовов. Конкретно int 0x80 считается устаревшим и медленным, но из соображений обратной совместимости он все еще работает. Далее мы рассмотрим и более новые механизмы.
Нетрудно догадаться, что eax — это номер системного вызова, а ebx, ecx и edx — его аргументы. Какой системный вызов имеет какой номер можно подсмотреть в файлах:
# для x86
/usr/include/x86_64-linux-gnu/asm/unistd_32.h
# для x64
/usr/include/x86_64-linux-gnu/asm/unistd_64.h
Следующая строчка из файла unistd_32.h:
… как бы намекает нам, что производится вызов write. В свою очередь, из man 2 write
мы можем узнать, какие аргументы этот системный вызов принимает:
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
То есть, рассмотренный код эквивалентен:
// напомню, что stdout == 1
write(stdout, «Hello, world!\n», 14)
Затем аналогичным образом производится вызов:
// команда `xor %ebx, %ebx` обнуляет регистр %ebx
exit(0)
Совсем не сложно!
В общем случае системный вызов через 0x80 производится по следующим правилам. Регистру eax присваивается номер системного вызова из unistd_32.h. До шести аргументов помещаются в регистры ebx, ecx, edx, esi, edi и ebp. Возвращаемое значение помещается в регистр eax. Значения остальных регистров при возвращении из системного вызова остаются прежними.
Выполнение системного вызова через sysenter
Начиная с i586 появилась инструкция sysenter, специально предназначенная (чего нельзя сказать об инструкции int) для выполнения системных вызовов.
Рассмотрим пример использования ее на Linux:
.data
msg:
.ascii «Hello, world!\n»
len = . — msg
.text
.globl _start
_start:
# write
mov $4, %eax
mov $1, %ebx
mov $msg, %ecx
mov $len, %edx
push $write_ret
push %ecx
push %edx
push %ebp
mov %esp, %ebp
sysenter
write_ret:
# exit
mov $1, %eax
xor %ebx, %ebx
push $exit_ret
push %ecx
push %edx
push %ebp
mov %esp, %ebp
sysenter
exit_ret:
Сборка осуществляется аналогично сборке предыдущего примера.
Как видите, принцип тот же, что при использовании int 0x80, только перед выполнением sysenter требуются поместить в стек адрес, по которому следует вернуть управление, а также совершить кое-какие дополнительные манипуляции с регистрами. Причины этого более подробно объясняются здесь.
Инструкция sysenter работает быстрее int 0x80 и является предпочтительным способом совершения системных вызовов на x86.
Выполнение системного вызова через syscall
До сих пор речь шла о 32-х битных программах. На x64 выполнение системных вызовов осуществляется так:
.data
msg:
.ascii «Hello, world!\n»
.set len, . — msg
.text
.globl _start
_start:
# write
mov $1, %rax
mov $1, %rdi
mov $msg, %rsi
mov $len, %rdx
syscall
# exit
mov $60, %rax
xor %rdi, %rdi
syscall
Собирается программа таким образом:
as —64 hello-syscall.s -o hello-syscall.o
ld -melf_x86_64 -s hello-syscall.o -o hello-syscall
Принцип все тот же, но есть важные отличия. Номера системных вызовов нужно брать из unistd_64.h, а не из unistd_32.h. Как видите, они совершенно другие. Так как это 64-х битный код, то и регистры мы используем 64-х битные. Номер системного вызова помещается в rax. До шести аргументов передается через регистры rdi, rsi, rdx, r10, r8 и r9. Возвращаемое значение помещается в регистр rax. Значения, сохраненные в остальных регистрах, при возвращении из системного вызова остаются прежними, за исключением регистров rcx и r11.
Интересно, что в программе под x64 можно одновременно использовать системные вызовы как через syscall, так и через int 0x80.
Отладка ассемблерного кода в GDB
Статья была бы не полной, если бы мы не затронули вопрос отладки всего этого хозяйства. Так как мы все равно очень плотно сидим на GNU-стэке, в качестве отладчика воспользуемся GDB. По большому счету, отладка не сильно отличается от отладки обычного кода на C, но есть нюансы.
Например, вы не можете так просто взять и поставить брейкпоинт на процедуру main. Как минимум, у вас попросту нет отладочных символов с информацией о том, где эту main искать. Решение заключается в том, чтобы самостоятельно определить адрес точки входа в программу и поставить брейкпоинт на этот адрес:
Увидим что-то вроде:
[…]
Entry point: 0x4000b0
[…]
Далее говорим:
Какого-либо исходного кода у нас тоже нет, поэтому команда l
работать не будет. Сами ассемблерные инструкции и есть исходный код! Так, например, можно посмотреть следующие 5 ассемблерных инструкций:
По понятным причинам, переход к очередной строчке кода при помощи команд n
или s
работать не будет. Вместо этих команд следует использовать команды перехода к следующей инструкции — ni
, si
, и так далее.
Смотреть и изменять значения переменных мы тоже не можем. Однако ничто не мешает смотреть и изменять значения регистров:
info registers
p/x $rcx
p $xmm1
set $r15 = 0x123
Наконец, стектрейсы нам тоже недоступны. Но ничто не мешает, например, посмотреть 8 ближайших значений на стеке:
По большому счету, это все отличие от отладки программы на C при наличии исходников. Кстати, вы можете легко посмотреть, в какой ассемблерных код транслируется ваш код на C, одним из следующих способов:
gcc -S test.c -o —
objdump -d ./myprog
Как альтернативный вариант, можно воспользоваться Hopper или подобным интерактивным дизассемблером.
Внезапно отладка программы, собранной без -g
и/или с -O2
, перестала казаться таким уж страшным делом, не так ли?
Заключение
В качестве домашнего задания можете попытаться написать программу на ассемблере, выводящую переменные окружения, а также переданные ей аргументы командной строки.
Примите во внимание, что в Linux есть еще как минимум два способа сделать системный вызов — через так называемые vsyscall (считается устаревшим, но поддерживается для обратной совместимости) и VDSO (пришедший ему на замену). Эти способы основаны на отображении страницы ядра в адресное пространство процесса и призваны ускорить выполнение системных вызовов, не требующих проверки привилегий и других тяжелых действий со стороны ядра системы. В качестве примера вызова, который может быть ускорен таким образом, можно привести gettimeofday. К сожалению, рассмотрение vsyscall и VDSO выходит за рамки данного поста. Больше информации о них вы найдете по приведенным ниже ссылкам.
Ссылки по теме:
Кроме того, вас могут заинтересовать статьи, посвященные ассемблеру, в замечательных блогах alexanius-blog.blogspot.ru и 0xax.blogspot.ru.
А какие инструменты (компилятор, отладчик, …) вы предпочитаете использовать для программирования на ассемблере?
Дополнение: Шпаргалка по основным инструкциям ассемблера x86/x64
Метки: Linux, Ассемблер.
Типы данных в ассемблере
Данные – числа и закодированные символы, используемые в качестве операндов команд.
Основные типы данных в ассемблере
Тип | Директива | Количество байт |
Байт | DB | 1 |
Слово | DW | 2 |
Двойное слово | DD | 4 |
8 байт | DQ | 8 |
10 байт | DT | 10 |
Данные, обрабатываемые вычислительной машиной, можно разделить на 4 группы:
- целочисленные;
- вещественные.
- символьные;
- логические;
Целочисленные данные
Целые числа в ассемблере могут быть представлены в 1-байтной, 2-байтной, 4-байтной или 8-байтной форме. Целочисленные данные могут представляться в знаковой и беззнаковой форме.
Беззнаковые целые числа представляются в виде последовательности битов в диапазоне от 0 до 2n-1, где n- количество занимаемых битов.
Знаковые целые числа представляются в диапазоне -2n-1 … +2n-1-1. При этом старший бит данного отводится под знак числа (0 соответствует положительному числу, 1 – отрицательному).
Вещественные данные
Вещественные данные могут быть 4, 8 или 10-байтными и обрабатываются математическим сопроцессором.
Логические данные
Логические данные представляют собой бит информации и могут записываться в виде последовательности битов. Каждый бит может принимать значение 0 (ЛОЖЬ) или 1 (ИСТИНА). Логические данные могут начинаться с любой позиции в байте.
Символьные данные
Символьные данные задаются в кодах и имеют длину, как правило, 1 байт (для кодировки ASCII) или 2 байта (для кодировки Unicode) .
Числа в двоично-десятичном формате
В двоично-десятичном коде представляются беззнаковые целые числа, кодирующие цифры от 0 до 9. Числа в двоично-десятичном формате могут использоваться в одном из двух видов:
- упакованном;
- неупакованном.
В неупакованном виде в каждом байте хранится одна цифра, размещенная в младшей половине байта (биты 3…0).
Упакованный вид допускает хранение двух десятичных цифр в одном байте, причем старшая половина байта отводится под старший разряд.
Числовые константы
Числовые константы используются для обозначения арифметических операндов и адресов памяти. Для числовых констант в Ассемблере могут использоваться следующие числовые форматы.
Десятичный формат – допускает использование десятичных цифр от 0 до 9 и обозначается последней буквой d, которую можно не указывать, например, 125 или 125d. Ассемблер сам преобразует значения в десятичном формате в объектный шестнадцатеричный код и записывает байты в обратной последовательности для реализации прямой адресации.
a DB 12
Шестнадцатеричный формат – допускает использование шестнадцатеричных цифр от 0 до F и обозначается последней буквой h, например 7Dh. Так как ассемблер полагает, что с буквы начинаются идентификаторы, то первым символом шестнадцатеричной константы должна быть цифра от 0 до 9. Например, 0Eh.
a DB 0Ch
Двоичный формат – допускает использование цифр 0 и 1 и обозначается последней буквой b. Двоичный формат обычно используется для более четкого представления битовых значений в логических командах (AND, OR, XOR).
a DB 00001100b
Восьмеричный формат – допускает использование цифр от 0 до 7 и обозначается последней буквой q или o, например, 253q.
a DB 14q
Массивы и цепочки
Массивом называется последовательный набор однотипных данных, именованный одним идентификатором.
Цепочка — массив, имеющий фиксированный набор начальных значений.
Примеры инициализации цепочек
M1 DD 0,1,2,3,4,5,6,7,8,9
M2 DD 0,1,2,3
DD 4,5,6,7
DD 8,9
Каждая из записей выделяет десять последовательных 4-байтных ячеек памяти и записывает в них значения 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Идентификатор M1 определяет смещение начала этой области в сегменте данных .DATA.
Для инициализации всех элементов массива одинаковыми значениями используется оператор DUP:
Идентификатор Тип Размер DUP (Значение)
Идентификатор — имя массива;
Тип — определяет количество байт, занимаемое одним элементом;
Размер — константа, характеризующая количество элементов в массиве
Значение — начальное значение элементов.
Например
a DD 20 DUP (0)
описывает массив a из 20 элементов, начальные значения которых равны 0.
Если необходимо выделить память, но не инициализировать ее, в качестве поля Значение используется знак ?. Например,
b DD 20 DUP(?)
Символьные строки
Символьные строки представляют собой набор символов для вывода на экран. Содержимое строки отмечается
- одиночными кавычками », например, ‘строка’
- двойными кавычками «», например «строка»
Символьная строка определяется только директивой DB, в которой указывается более одного символа в последовательности слева направо.
Символьная строка, предназначенная для корректного вывода, должна заканчиваться нуль-символом ‘\0’ с кодом, равным 0.
Str DB ‘Привет всем!’, 0
Для перевода строки могут использоваться символы
- возврат каретки с кодом 13 (0Dh)
- перевод строки с кодом 10 (0Ah).
Stroka DB «Привет», 13, 10, 0
Назад
Назад: Язык ассемблера
плоский монтажник
плоский монтажник
плоский ассемблер
Компилятор языка ассемблера с открытым исходным кодом.
Главный индекс
Скачать
Документация
Примеры
Доска объявлений
Плоский ассемблер (сокращенно fasm, намеренно стилизованный строчными буквами) — это быстрый ассемблер, работающий во множестве операционных систем, непрерывно развивающийся с 1999 года.
Он был разработан в первую очередь для сборки инструкций x86 и поддерживает наборы инструкций x86 и x86-64 с такими расширениями, как MMX, 3DNow !, SSE до SSE4, AVX, AVX2, XOP и AVX-512.Он может производить вывод в простом двоичном формате, формате MZ, PE, COFF или ELF.
Он включает мощную, но простую систему макрокоманд и выполняет несколько проходов для оптимизации размера кодов инструкций.
Плоский ассемблер является самостоятельным хостингом, и в него включен полный исходный код.
Единственная разница между плоскими версиями ассемблера, включенными в следующие пакеты, — это операционная система, в которой они могут выполняться.
Для любого заданного исходного текста каждая версия будет генерировать точно такой же выходной файл, поэтому каждый из следующих выпусков можно использовать для компиляции программ для любой операционной системы.
Плоский монтажник сделан одним человеком — Томашем Грыштаром — в качестве хобби. Хотя это бесплатное программное обеспечение с открытым исходным кодом, мы приветствуем пожертвования, которые помогут покрыть затраты и потерю времени. Это большое подспорье в поддержании этого проекта. Если вы хотите сделать пожертвование автору, нажмите кнопку рядом. | |
плоский ассемблер 1.73.27 для Windows размер: 1036 килобайт последнее обновление: 21 апр 2021 г. 13:12:46 UTC | Помимо версии для командной строки для консоли Windows, этот пакет содержит версию со встроенным редактором подсветки синтаксиса, так что вы можете редактировать, компилировать и выполнять свои программы из одного места.Также он содержит набор включений с уравнениями и макроинструкциями для программирования Windows и некоторыми примерами программ Windows, созданных с помощью помощь от них. Предоставляемая документация находится в формате PDF. |
плоский ассемблер 1.73.27 для Linux размер: 343 килобайта последнее обновление: 27 января 2021 г., 10:08:11 UTC | Это версия для систем Linux, работающих на процессорах, совместимых с x86 или x64. Включает документацию в чистом формате ASCII и некоторые примеры программ Linux. |
плоский ассемблер 1.73.27 для DOS размер: 447 килобайт последнее обновление: 27 января 2021 г., 10:07:28 UTC | Эта версия может быть запущена из командной строки любой операционной системы, совместимой с DOS, и содержит несколько крошечных примеров программ DOS. Он также содержит документацию в текстовом формате с использованием набора символов DOS. Если вы хотите использовать плоский ассемблер из командной строки системы Windows, вам следует использовать консольную версию Windows вместо этой. |
плоский ассемблер 1.73.27 для Unix / libc размер: 274 килобайт последнее обновление: 27 января 2021 г., 10:08:11 UTC | Это версия для всех платформ, которые поддерживают объектный формат ELF и библиотеку C, например OpenBSD или Zeta. Объектный файл, представленный в этом пакете, может быть связан с 32-битной библиотекой C для создания окончательного исполняемого файла. для любой такой системы. Включена документация в чистом формате ASCII. |
Плоский ассемблер g (сокращенно fasmg) — это новый ассемблерный движок, созданный как преемник того, что используется в плоском ассемблере 1.Вместо того, чтобы иметь встроенную поддержку инструкций x86, он реализует их с помощью дополнительных пакетов и таким же образом может быть адаптирован для сборки для различных архитектур и целей.
С помощью включенных примеров пакетов он способен генерировать все выходные форматы, которые может использовать плоский ассемблер 1, и дополнительные, такие как Mach-O или Intel HEX.
плоский ассемблер g jaf7 размер: 516 килобайт последнее обновление: 02 мая 2021 г., 9:47:49 UTC | Этот выпуск содержит исполняемые файлы для Linux, Windows и MacOS.Он упакован с примерами макрокоманд, которые позволяют собирать простые программы для таких архитектур, как x86, x64, 8052, AVR или виртуальная машина Java. Дополнительные примеры и определения наборов инструкций для других архитектур можно найти в следующих разделах этого веб-сайта. |
Ниже перечислены сторонние продукты, основанные на плоском ассемблере, которые можно загрузить с соответствующих веб-сайтов.
ФАСМАРМ | Кросс-ассемблер для архитектур ARM на основе плоского ассемблера 1, доступный в версиях для Windows и Linux. |
Главный индекс
Скачать
Документация
Примеры
Доска объявлений
Copyright © 1999-2020, Томаш Грыштар. Также на GitHub, YouTube, Twitter.
Сайт работает на rwasa.
плоский монтажник
плоский монтажник
плоский ассемблер
Документация и руководства.
Главный индекс
Скачать
Документация
Примеры
Доска объявлений
В этом разделе представлены доступные для просмотра версии руководств и другой документации, включенной в пакеты плоского ассемблера, а также несколько других соответствующих текстов.Если вам нужны базовые руководства по языку ассемблера, посетите официальный видеоканал и наши форумы.
Во-первых, несколько документов, касающихся нового двигателя плоской сборки g.
плоский сборщик g Введение и обзор последнее обновление: 03 фев 2020 г. | Введение в плоский ассемблер g, показывающее назначение этого двигателя и демонстрирующее как построить ассемблер для данной архитектуры ЦП с помощью макрокоманд. |
плоский сборщик g Руководство пользователя последнее обновление: 29 авг 2020 | Подробное описание синтаксиса плоского ассемблера g. Это справочный документ, который также можно рассматривать как прогрессивное руководство. |
Остальные документы касаются оригинального плоского сборщика.
плоский ассемблер 1.73 Programmer’s Manual последнее обновление: 20 авг.2020 г. | Это HTML-версия документации, которая поставляется со всеми пакетами плоского ассемблера 1.Он содержит обзор синтаксиса и перечисляет все поддерживаемые инструкции и директивы, с некоторыми элементарные примеры использования. Чтение этого документа особенно рекомендуется, если у вас есть опыт программист на языке ассемблера, но вы не знакомы с синтаксисом плоского ассемблера. |
Windows Programming , последнее обновление: 19 апреля 2016 г. | Это документация к стандартному набору включений, который поставляется с пакетом плоского ассемблера 1 для Windows.Он фокусируется на документировании макроинструкций, предоставляемых этим пакетом, которые предназначены для упрощения написания программ для этого. операционной системы, а также для эмуляции синтаксических структур, обычно используемых другими ассемблерами для этой среды. |
Понимание плоский ассемблер последнее обновление: 06 апр 2016 | Это расширенное руководство по различным уровням плоского ассемблера 1, он показывает и объясняет некоторые уловки, которые вы можете делать, однако его основная цель — объяснить взаимодействие между различными особенностями ассемблера и препроцессора, что иногда может сбивать с толку, если вы не понимаете что именно там происходит. |
Принципы дизайна , последнее обновление: 9 февраля 2009 г. | Старый обзор принципов, которые повлияли на конструкцию плоского ассемблера 1. Этот текст был написан, чтобы помочь понять, почему он придерживался некоторых других вариантов, чем другие ассемблеры, для каких основных целей он изначально создавался и в каких направлениях может развиваться. |
Главный индекс
Скачать
Документация
Примеры
Доска объявлений
Copyright © 1999-2020, Томаш Грыштар.Также на GitHub, YouTube, Twitter.
Сайт работает на rwasa.
Форум | Посты | Резьба | Последнее сообщение | Модератор | ||||
Официальный | ||||||||
Assembly Статьи и комментарии автора плоского ассемблера, касающиеся языков ассемблера или вычислений в целом. | 167 | 11 |
| |||||
Peripheria Работы и мнения автора плоского ассемблера по темам, не имеющим прямого отношения к программированию. | 16 | 6 |
| |||||
Общие | ||||||||
Main Общее обсуждение плоского ассемблера, не связанного с какой-либо конкретной операционной системой и / или средой. | 30895 | 3023 | Модераторы | |||||
Учебники и примеры Официальные и неофициальные учебники и примеры, обучающие различным аспектам программирования на ассемблере. Вы также можете разместить свой собственный. | 1800 | 210 |
| |||||
DOS Здесь вы можете задавать вопросы, связанные с программированием на ассемблере в среде DOS. | 7412 | 804 |
| ДОС 386 | ||||
Windows Все, что касается программирования Win32 / Win64 с помощью fasm, должно быть здесь. | 32319 | 3799 | ||||||
Linux Здесь можно задать любой вопрос о программировании на языке ассемблера Linux с помощью fasm. | 4153 | 527 | пелайло | |||||
Unix Это место для обсуждения использования плоского ассемблера в системах Unix, таких как FreeBSD, OpenBSD, MacOS (OS X) или BeOS. | 515 | 66 | CRC | |||||
MenuetOS Форум, посвященный Menuet — операционной системе, написанной с использованием fasm. | 3829 | 628 |
| Ville | ||||
специальный | ||||||||
Макроинструкции Разместите здесь свои полезные макроинструкции, обсудите различные приемы и настройки синтаксиса. | 7108 | 1088 |
| |||||
Конструкция ОС Разместите здесь, если вы пишете собственное ядро ОС, загрузчик и т. Д. | 13488 | 1300 |
| |||||
IDE Development Для разработчиков и пользователей интегрированных сред разработки для плоского ассемблера. | 4329 | 421 | ||||||
Проекты и идеи Публикуйте идеи для написания программ, обсуждайте такие идеи и дизайн, ищите других программистов, которые помогут начать проект. | 4795 | 356 |
| |||||
Архитектуры, отличные от x86 Модификации плоского ассемблера, которые позволяют кросс-сборку кода для архитектур микропроцессоров, отличных от x86, например ARM.Также любые общие обсуждения, касающиеся таких архитектур. | 1992 | 151 | ||||||
Языки высокого уровня Обсуждение компиляторов языков высокого уровня, использующих плоский ассемблер в качестве бэкэнда, а также о смешивании кода ассемблера с другими языками и т. Д. | 2889 | 259 | Каин | |||||
Дизайн языков программирования Обсудить дизайн языков программирования и создание компиляторов, интерпретаторов и ассемблеров. | 874 | 65 | ||||||
Внутреннее устройство компилятора Здесь вы можете задавать вопросы об исходном коде fasm, сообщать об ошибках, вносить изменения. | 7307 | 941 |
| |||||
Прочие | ||||||||
Отзыв Пожалуйста, размещайте здесь любые комментарии или предложения, касающиеся этого форума. | 2186 | 246 | ||||||
Кто на сайте | ||||||||
Всего в сети 2 пользователей: 2 зарегистрированных, 0 скрытых и [ Администратор ] [ Модератор ] Зарегистрированных пользователей: Overclick, sinsi Максимальное количество зарегистрированных пользователей, когда-либо находившихся в сети, было 11 17 мая 2020 года, 13:54 | ||||||||
Последний зарегистрированный пользователь: realbogart |
Fractal Explorer 64 размер: 100 килобайт | Мандельброт установил проводник для 64-битной Windows, реализующий пути кода FPU, SSE, AVX и FMA. Написано tthsqe (2011). |
Размер Base Converter : 2 килобайта | Преобразование между разными системами счисления. Написано Томми Лиллехагеном (2003). |
Параметры командной строки размер: 2 килобайта | Обработка параметров командной строки в Windows. Написано Теодором-Юлианом Чобану (2004). |
Пример подключения Windows размер: 3 килобайта | Модификация кода операции во время выполнения и подключение API методом обхода. Написано Брайаном Пауэром / RedGhost (2006). |
FASMCam размер: 1 килобайт | Доступ к веб-камере в Windows. Написано Маркусом Араужо (2005). |
Примеры GTK размер: 6 килобайт | Несколько небольших примеров программирования GTK в Linux. Автор Свен Блюменштейн (2003). |
Вызов классов Java из сборки размер: 3 килобайта | Консольное приложение для Win32, использующее JVM.DLL-интерфейс для вызова некоторых классов Java из кода сборки. Автор Томаш Грыштар (2009). |
двигатель kelvar unREAL размер: 1835 килобайт | Простой игровой движок для DOS, работающий в 32-битном нереальном режиме. Здесь также показано, как использовать VESA и Sound Blaster. Автор Томаш Грыштар (2001). |
Прозрачное окно размер: 2 килобайта | Пример использования полосы прокрутки для установки прозрачности окна. Автор Карлос Эрнандес / кокос (2007). |
Вход в длинный режим размер: 3 килобайта | Простейшие примеры входа в длинный режим, начиная с реального режима. Автор Томаш Грыштар (2007). |
Сборка микширования с MS Visual C размер: 2 килобайта | Несколько продвинутый пример смешивания сборки и C. Он использует MS Visual C, но может применяться к другим компиляторам C. Автор видео (2006). |
Загрузчик FAT12 размер: 13 килобайт | Загрузчик, способный читать и выполнять код из заданного файла, хранящегося на гибком диске. Автор Леонид Петров (2002). |
Quetannon размер: 9 килобайт | Демонстрация использования библиотеки WinSock для установления соединений TCP / IP. Автор Томаш Грыштар (2003). |
Скриншот в формате JPEG с GDI + размером: 1 килобайт | Простой пример использования библиотеки GDI +.Он делает снимок экрана и сохраняет его в файл JPEG. Автор Томаш Грыштар (2009). |
SEH / Hardware Breakpoint в Win32 размер: 3 килобайта | Пример, который добавляет обработчик исключения, точки останова, обрабатывает исключение и продолжает выполнение, а затем создает фатальное исключение. Обработчик исключений отображает пользователю всю информацию об исключении. Написано Брайаном Пауэром / RedGhost (2006). |
Размер SysTray : 2 килобайта | Простой пример приложения в трее Windows. Написано Матеушем Тимеком (2004). |
Пример драйверов Win64 размер: 37 килобайт | Несколько примеров драйверов для 64-битной Windows с набором небольших приложений для их установки и удаления. Автор Франтишек Габриш (2006). |
Давайте узнаем сборку x86-64! Часть 1
Этот пост является частью серии статей о программировании на ассемблере x86-64, которую я пишу.Проверьте часть 0 .
В предыдущей части мы рассмотрели множество вопросов за короткое время — от общего введения и описания того, как работают регистры и память, до фактического вызова функций Windows API. В этом я хочу представить некоторые важные особенности Flat Assembler — макросы, переменные времени сборки и условную сборку, а также пару других. Мы будем использовать их, чтобы облегчить вызов функций Windows API, и напишем наше первое «Hello, World!». приложение.
Почему макросы?
Переходя с C ++, у вас могут возникать ужасающие воспоминания, когда вы слышите слова «макрос» или «препроцессор». В самом деле, мудрый совет — избегать использования препроцессора, пока есть способ добиться того, что вы пытаетесь сделать, только с помощью самого языка.
Совершенно иная ситуация на сборочной земле. Не так уж много «языка», о котором можно было бы говорить, и существует множество часто повторяющихся шаблонов (мы видели один пример — соглашения о вызовах).Программирование на ассемблере может оказаться довольно утомительным. Можно сказать, что именно поэтому были изобретены языки высокого уровня, и это достаточно справедливо. Но, если вы собираетесь писать ассемблер вручную по какой-либо причине, можно также дать себе инструменты для создания некоторого подобия высокоуровневых конструкций. Вот почему большинство ассемблеров разработали довольно сложные макросистемы и даже средства метапрограммирования, которые, как мы увидим, намного мощнее препроцессора C ++.
Макросистема FASM
FASM позволяет нам определять наши собственные пользовательские инструкции (которые в руководстве называются «макроинструкциями»).В этом тексте мы рассмотрим самое необходимое, что нам понадобится для наших целей. Как всегда, читайте документацию, если вас интересуют подробности.
Новая макрокоманда определяется с помощью директивы macro
. Давайте поэкспериментируем. Откройте FASMW.EXE и вставьте следующий код:
use64
macro add5 target {
добавить цель, 5
}
add5 rax
Директива use64
вверху указывает FASM разрешить использование 64-битных инструкций и регистров.За директивой макроса
следует имя макроса, за которым следует список параметров, и тело макроса заключено в фигурные скобки. В нашем случае имя макроса — add5
, у него всего один параметр — то, к чему нужно добавить 5. Последняя строка просто вызывает макрос, он будет заменен на add rax, 5
во время предварительной обработки. Если вы сейчас нажмете Ctrl + F9, FASM соберет данный код и даже создаст двоичный файл. Однако созданный двоичный файл на самом деле не может быть запущен вашей ОС — он не в исполняемом формате, таком как PE или ELF.Фактически, FASM не требует, чтобы вывод был в каком-либо конкретном формате — по умолчанию он выдает просто поток байтов, в данном случае — необработанный машинный код, двоичное представление инструкций сборки из входного файла.
Давайте немного улучшим наш макрос. По умолчанию FASM позволяет пропускать некоторые аргументы при вызове макроса. Если поставить звездочку рядом с именем соответствующего параметра в определении макроса, то он будет помечен как обязательный:
use64
macro add5 target * {
добавить цель, 5
}
add5 rax
Если теперь вы попытаетесь вызвать add5
без каких-либо аргументов, это вызовет ошибку «недопустимые аргументы макроса» (если вы попробуете это, не пометив параметр как требуемый, все равно будет ошибка, возникающая в результате попытки синтаксического анализа строки add , 5
)
В C вы можете определять макросы с произвольным числом аргументов (они называются макросами с переменным числом аргументов).Препроцессор FASM предоставляет эффективный способ работы с такими макросами. Давайте посмотрим, как определить макрос с произвольным количеством аргументов.
макрос foo a, [b, c] {
общий ; мы объясним, что означает «общий» позже
дб а, б
db a, c
}
foo 0, 1, 2, 3, 4
Это эквивалентно:
дб 0, 1, 3
дб 0, 2, 4
«Вариативная» часть параметров заключена в квадратные скобки в конце списка параметров макроса.Квадратные скобки означают, что эту группу параметров можно повторять произвольное количество раз. В приведенном выше случае a
соответствует самому первому аргументу, в то время как b
и c
соответствуют всем нечетным и четным аргументам, следующим за ним, другими словами: часть в квадратных скобках многократно «сопоставляется» с остальными списка аргументов. Эти заключенные в квадратные скобки аргументы называются групповыми аргументами или групповыми аргументами на жаргоне FASM.
Теперь давайте обратим наше внимание на загадочную директиву common
.
Каждый макрос FASM представляет собой последовательность кодовых блоков, каждый из которых имеет один из следующих типов: общий
, прямой
и обратный
. По умолчанию, когда вы запускаете макрос, и у него нет никаких групповых аргументов, считается, что он находится в обычном режиме
. С другой стороны, макросы с групповыми аргументами запускаются в режиме вперед
.Мы можем завершить текущий блок и начать новый, вызвав директиву common
, forward
или reverse
в теле макроса.
Типы блоков различаются тем, как они обрабатывают ссылки на групповые аргументы.
Когда имя группового аргумента встречается в пределах общего блока
, оно заменяется всеми аргументами, которые ему соответствуют. Поэтому примерно так:
макрос WinStr labelName *, [args *] {
общий
labelName db args, 0x0D, 0x0A
}
WinStr foo 1, 2, 3
Будет заменено на:
foo db 1, 2, 3, 0x0D, 0x0A
вперед
блока работают немного иначе.Прямой блок повторяется N / M раз, где N — общее количество аргументов (не считая тех, которые могут быть сопоставлены с параметрами, не заключенными в квадратные скобки), а M — количество параметров в квадратных скобках.
Для каждого повторяющегося экземпляра ссылки на групповой аргумент внутри блока заменяются значением соответствующего аргумента.
Таким образом, учитывая что-то вроде этого:
макрос foo a, [b, c] {
вперед
db b, a, c
}
foo 0, 1, 2, 3, 4
Препроцессор выдаст:
; 0 присваивается.; 1 и 2 присваиваются значениям b и c соответственно для первого экземпляра блока "вперед".
; 3 и 4 присваиваются значениям b и c соответственно для второго экземпляра блока "вперед".
дб 1, 0, 2
дб 3, 0, 4
Блоки обратный
работают точно так же, как вперед
, за исключением того, что порядок аргументов, как следует из названия, обратный.
Теперь мы можем написать макрос, который суммирует набор значений и записывает результат в регистр:
use64
цель накопления макроса *, [термин *] {
общий
xor цель, цель
вперед
добавить цель, срок
}
накопить rax, 1, 2, 4
Он устанавливает цель в 0 (путем xor-ing ее с самим собой), затем генерирует соответствующую инструкцию добавления для каждого из значений, переданных в качестве последующих аргументов.
Метапрограммирование
Переменные времени сборки
Когда вы пишете что-то вроде foo = 3
в FASM, он вводит новую переменную времени сборки . Несмотря на то, что официальное руководство FASM иногда называет их «константами» (видимо, по историческим причинам), на самом деле они являются переменными: вы можете их изменить. Проверь это:
arg_count = 0
макрос count_args [arg] {
arg_count = arg_count + 1
}
count_args a, b, c, d, e, f, g
db arg_count
Если вы соберете этот файл и откроете полученный двоичный файл, вы увидите, что он состоит из одного байта со значением 7!
Условная сборка и петли
Переменные времени сборки могут использоваться в условиях для конструкций if-else времени сборки.Они позволяют обрабатывать или пропускать определенный блок кода в зависимости от условия. Например, мы можем добавить верхний предел к количеству аргументов, переданных предыдущему макросу:
arg_count = 0
макрос count_args [arg] {
если arg_count> 9
display "Слишком много аргументов!"
ошибаться
конец, если
arg_count = arg_count + 1
}
count_args a, b, c, d, e, f, g
db arg_count
В приведенном выше примере представлена пара полезных директив — display
показывает сообщение журнала во время сборки, а err
заставляет ассемблер прерывать работу с ошибкой.
Это не ограничивается условиями: вы также можете писать циклы во время сборки!
; показывает биты значения в порядке справа налево
macro showbits_rtl arg {
val = arg
пока val> 0
дисплей (val и 1) + '0'
val = val shr 1
конец пока
}
showbits_rtl 13
Сравнение типов выражений
FASM имеет встроенный оператор eqtype
, который принимает два выражения сборки и выдает значение «истина», если оба выражения дают один и тот же тип, и «ложь» в противном случае.Конечно, мы можем использовать его во время сборки. Давайте изменим наш макрос накопления из более раннего, чтобы заставить цель всегда быть регистром:
use64
цель накопления макроса *, [термин *] {
если ~ (целевой тип rax)
отображение "накопление: цель должна быть регистром (было", `цель,") "
ошибаться
конец, если
общий
xor цель, цель
вперед
добавить цель, срок
}
накопить rcx, 1, 2, 4
Обратите внимание, что rcx eqtype rax
возвращает истину, поскольку оба выражения имеют один и тот же тип.Оператор обратной кавычки, который мы используем в отчете об ошибке, превращает аргумент макроса в строковый литерал.
соответствует
Директиве
FASM позволяет ввести определенное количество нового синтаксиса с помощью специальной директивы match
, которая заставляет блок кода обрабатываться, когда входная последовательность соответствует определенному шаблону.
сопоставить a .. b, 5 .. 10 {
я = а
в то время как я
Мы можем обернуть его в макрос, который позволяет нам определять последовательный диапазон байтов:
macro byterange rng {
; обратите внимание, что FASM требует, чтобы мы избегали фигурных скобок в теле макроса
совпадение.. b, rng \ {
я = а
в то время как я
Переменные времени сборки с прямой ссылкой
Последнее, что я хочу упомянуть, — это удивительное и противоречащее интуиции свойство переменных времени сборки. FASM позволяет ссылаться на переменные времени сборки до того, как они будут определены (это называется прямой ссылкой). Следующий код полностью в порядке и выдаст двоичный файл, состоящий из одного байта со значением 2:
db foo
foo = 2
Это может показаться простым, хотя и немного странным, но все может стать намного более странным:
db x, y
х = 6 - у
у = 2 * х
Да, этот код успешно соберет и создаст двоичный файл с двумя байтами: 2 и 4! Удивительно, но FASM может вычислить значения x и y, которые удовлетворяют обоим их определениям.Это на самом деле задумано.
Насколько я могу судить, корни этой специфической особенности кроются в том факте, что FASM очень одержим идеей создания минимально возможной формы машинного кода.
На x86 могут быть разные возможные последовательности байтов, соответствующие одной и той же удобочитаемой инструкции сборки. В частности, jmp labelname
может быть представлен по-разному, в зависимости от адреса целевой метки.Более того, поскольку переходы в сборке могут быть не только назад, но и вперед, мы должны иметь возможность ссылаться на метки, которые еще не были определены. Мы не узнаем, какая форма перехода является оптимальной, когда мы сталкиваемся с переходом вперед: в то время целевой адрес еще не был определен! Итак, что делает FASM, так это предполагает, что самая короткая форма может быть выдана для всего на первом проходе. Если это не сработает, выполняется второй проход (исправление некоторых «коротких» инструкций и исправление адресов), затем еще один и т. Д.до тех пор, пока либо все не сработает, либо FASM не решит сдаться. Это многопроходное разрешение применяется не только к адресам меток, но и к значениям переменных времени сборки (на самом деле, я почти уверен, что FASM обрабатывает метки и переменные времени сборки одинаково). Какой бы алгоритм ни использовался для предсказания значений переменных, он достаточно «умен», чтобы решать системы простых линейных уравнений (хотя я не пробовал более сложные).
Упрощение вызовов функций
Вооружившись этими новыми инструментами, мы можем сделать импорт и вызов функций Windows API намного менее громоздкими.На самом деле, FASM предоставляет удобную библиотеку макросов, которые делают именно это, но я обещал действовать как можно «с нуля», так что никаких библиотек для нас не было 🙂
Создание таблиц импорта PE
Начнем с написания пары макросов, которые упростят запись раздела импорта наших PE-файлов. Это для таблицы каталога импорта:
macro import_directory_table [lib] {
; для каждой библиотеки определите запись IDT
вперед
; обратите внимание, что IAT и ILT одинаковы.; IAT определяется с помощью макроса import_functions.
dd rva IAT __ # lib
дд 0
дд 0
dd rva ИМЯ __ # lib; ptr в таблицу имен библиотеки.
dd rva IAT __ # lib
; завершить IDT нулевой записью.
общий
dd 5 dup (0)
; таблица строк имен библиотек.
вперед
ИМЯ __ # lib db `lib," .DLL ", 0
Довольно просто. Обратите внимание, что #
выполняет вставку токенов, аналогично препроцессору C (т.е.е. вставляет значение аргумента непосредственно в тело макроса).
Далее, макрос для создания таблиц адресов импорта и подсказок / имен для импортированных функций:
макрос import_functions имя_библиотеки, [funcnames] {
; определить таблицу подсказок / имен
вперед
; убедитесь, что записи выровнены по четному адресу.
если $ & 1
db 0
конец, если
IMPORTNAME __ # funcnames dw 0
db `funcnames, 0
; Определение IAT
общий
IAT __ # имя_библиотеки:
; каждая запись является точкой в ранее определенной таблице подсказок / имен.; записи должны быть перезаписаны фактическими адресами функций во время выполнения.
вперед
funcnames dq rva IMPORTNAME __ # funcnames
; завершить IAT нулевой записью.
общий
dq 0
}
С помощью этих двух макросов мы можем переписать наш раздел импорта PE:
раздел '.idata' импортировать доступный для чтения, доступный для записи
; сгенерируйте таблицу каталогов импорта, включите KERNEL32.DLL и USER32.DLL
import_directory_table KERNEL32, USER32
; Функции для импорта из KERNEL32
import_functions KERNEL32, ExitProcess
; Функции для импорта из USER32
import_functions USER32, MessageBoxA
Реализация соглашения о вызовах 64-битной Windows
В предыдущей части этой серии мы обсуждали соглашение о вызовах 64-разрядной версии Windows. У него довольно много правил, и обеспечение их выполнения до вызова функции довольно громоздко.Давайте напишем многоразовый макрос, который сделает всю работу за нас.
Обратите внимание, что мы не будем полностью реализовывать соглашение о вызовах (например, я не буду беспокоиться о поддержке аргументов с плавающей запятой), но этого будет достаточно для целей этих руководств. По сути, мы просто убедимся, что стек правильно выровнен и имеет достаточно места для всех аргументов, и поместим аргументы в соответствующие регистры или места в стеке.
Мы начнем с небольшого вспомогательного макроса, который перемещает свой первый аргумент в регистр, обозначенный
второй аргумент, если оба аргумента не относятся к одному и тому же регистру.
макрос call64_putreg param *, reg *
{
если ~ (reg eqtype rax)
отображение "цель должна быть регистром"
ошибаться
конец, если
если ~ param eq reg
mov reg, param
конец, если
}
А вот и основной макрос, реализующий соглашение о вызовах. См. Встроенные комментарии для объяснения того, как это работает:
; (Частичная) реализация соглашения о вызовах Win64 макрос call64 fn *, [arg] { общий ; Директива local объявляет следующие имена ; «локальный» макрос - это сделано для того, чтобы каждый ; вызов макроса получает свой собственный экземпляр этих переменных.локальные Нарги, arg_idx, stack_space ; nargs - это количество аргументов, переданных функции. ; обратите внимание, что ниже мы просто ссылаемся на nargs и полагаемся ; на fasm, чтобы вывести фактическое значение (см. раздел выше, посвященный прямым ссылкам). ; выровняйте стек по 16-байтовой границе и зарезервируйте место для аргументов. ; мы делаем предположение, что во время вызова макроса стек ; выровнен по типу "16 + 8" (из-за того, что в него был добавлен адрес возврата ; вызывающим текущую функцию).если наркотики
Посмотрим, Hello World!
Наконец, мы можем использовать наш новый макрос для более удобного вызова функций WinAPI. К настоящему времени у вас есть все необходимое для его самостоятельного создания, но для полноты картины приведен полный список программы, которая вызывает MessageBox, а затем завершает работу:
формат PE64 NX GUI 6.0
начало записи
macro import_directory_table [lib] {
вперед
dd rva IAT __ # lib
дд 0
дд 0
dd rva ИМЯ __ # lib
dd rva IAT __ # lib
общий
dd 5 dup (0)
вперед
ИМЯ __ # lib db `lib,".DLL ", 0
}
макрос import_functions имя_библиотеки, [funcnames] {
вперед
если $ & 1
db 0
конец, если
IMPORTNAME __ # funcnames dw 0
db `funcnames, 0
общий
IAT __ # имя_библиотеки:
вперед
funcnames dq rva IMPORTNAME __ # funcnames
общий
dq 0
}
макрос call64_putreg param *, reg *
{
если ~ (reg eqtype rax)
отображение "цель должна быть регистром"
ошибаться
конец, если
если ~ param eq reg
mov reg, param
конец, если
}
макрос call64 fn *, [arg]
{
общий
локальные Нарги, arg_idx, stack_space
если наркотики
На этом все.Надеюсь, это не было слишком скучно - лично я нахожу инструменты метапрограммирования, предоставляемые FASM, весьма впечатляющими по сравнению с некоторыми другими языками. Мы будем использовать многое из этого в следующих частях.
Понравился пост? Следите за этим блогом в Twitter, чтобы узнать больше!
Что такое FASM, краткое введение в Flat Assembler (FASM), FASM против MASM, инструменты для торговли.
Автор: shoorick
Заявление об ограничении ответственности: Эта тема представляет собой лишь краткое общее введение в FASM и адресована тем, кто никогда не использовал ее или даже никогда о ней не слышал.
Введение
FASM — это 32-разрядный кроссплатформенный ассемблер с открытым исходным кодом, предназначенный для архитектур IA-32 и x86-64 (кроме того, FASMARM — в неофициальном порте FASM, нацелен на архитектуру ARM). Существуют сборки для разных платформ, включая DOS, Windows и Linux.
Каждая сборка отличается только платформой, на которой должен работать компилятор, но все сборки имеют общие характеристики, такие как, например, возможность разработки приложений для платформ Windows на машине Linux и наоборот.
Хотя FASM создается одним человеком (Томаш Грыштар, он же Привалов), это очень мощный инструмент, способный управлять сложными, реальными проектами.
Что нам нужно, чтобы попробовать FASM?
Самое меньшее, что нам нужно сделать, это загрузить с платы FASM пакет, соответствующий нашей системе — для Windows архив, который мы должны загрузить, называется fasmw.zip.
Вышеупомянутый архив содержит:
● fasm.exe (ассемблер консоли Win32). ● fasmw.exe (GUI IDE со встроенным ассемблером). ● fasm.pdf (Руководство). ● ВКЛЮЧИТЬ (Папка с включениями для сборки приложений win32) . ● ПРИМЕРЫ (Примеры создания приложений win32 с fasm) . ● ИСТОЧНИКОВ (Источники fasm и fasmw). |
Итак, если у нас есть полный пакет FASM, мы можем запустить fasmw.exe »(официальная среда разработки FASM) и сразу приступить к разработке приложения на ассемблере.
В качестве альтернативы мы можем использовать любую другую IDE; в этом случае все, что нам нужно, это ассемблер FASM (fasm.exe). Конечно, если мы планируем разработать приложение, ориентированное на win32, нам также понадобятся файлы INCLUDE (заголовки).
Размер вышеупомянутых двоичных файлов (fasmw.exe, fasm.exe) чрезвычайно мал: 120 и 80 КБ соответственно.
Давайте создадим простейшее возможное 16-битное приложение …
Запустите fasmw (FASM IDE) и введите: ret
Сохраните файл как «.asm «и скомпилируйте его, используя ярлык:» Ctrl + F9 «.
Теперь просто переименуйте полученное двоичное расширение с «.bin» на «.com». Поздравляем, вы только что создали действующее приложение DOS, которое запускается и просто возвращается. Конечно, только что созданный двоичный файл выполняется, но это еще не правильный файл .com, так как начальное смещение равно 0.
Чтобы создать правильное приложение .com, мы должны добавить несколько строк в начало листинга сборки:
использовать 16
орг 100ч
ret
Теперь выходной двоичный файл также будет иметь символ «.com «, как обозначено. use16 в этом случае является необязательным, но требовалось для старой версии fasm, которая по умолчанию создавала 32-битный код.
Пример 16-битного «Hello, World!» приложение, закодированное с помощью FASM, представляет собой пример «COMDEMO», включенный в пакет fasm.zip:
; fasm пример записи 16-битной программы COM
орг 100ч; код начинается со смещения 100h
use16; использовать 16-битный код
display_text = 9
mov ах, display_text
mov dx, привет
внутр 21ч
внутр 20ч
hello db ‘Hello world!’, 24ч
В чем разница между FASM и MASM?
Основное различие между FASM и MASM заключается в синтаксисе адресации:
Загрузка адреса:
● Эквивалентный синтаксис в MASM: mov eax, смещение memvar
● Эквивалентный синтаксис в FASM: mov eax, memvar
Загрузка значения:
● Эквивалентный синтаксис в MASM: mov eax, memvar
● Эквивалентный синтаксис в FASM: mov eax, [memvar]
Можно ли создать приложение Win32 с помощью FASM?
Написание приложения Win32 в большинстве случаев аналогично написанию его в MASM, но с некоторыми отличиями; наиболее заметным является использование вызова и синтаксиса высокого уровня.
вызов в FASM реализован как внешний макрос; как таковой, он не может определить, вызывается ли вызываемая функция через импорт или напрямую, или это тип stdcall или c (директива PROTO не используется в FASM).
Другими словами, ключевое слово invoke в MASM должно быть заменено в FASM соответствующим макросом:
● вызвать (для функции stdcall через импорт).
● cinvoke (для функции c через импорт).
● stdcall (для прямого вызова функции stdcall).
● ccall (для функции прямого вызова c).
Это только мое личное мнение, но я не могу сказать, что это неудобно, так как программист на ассемблере должен точно знать, что он делает.
Кроме того, в MASM количество параметров функции должно соответствовать прототипу функции, тогда как в FASM это не обязательно.
Иногда это может быть очень удобно.Например, если у вас есть значение в регистре, и вам нужно передать его в качестве параметра для вызова функции, вы можете временно сохранить его в стеке, выполнить некоторые другие действия, извлечь его из стека, отправить его, а затем вызвать функция, которая будет использовать его с меньшим количеством параметров в строке вызова. Если вы понимаете, что делаете, это может дать вам реальное преимущество.
Но если вы хотите включить проверку параметров во избежание ошибок, это тоже возможно. Читать дальше…
В папке INCLUDE есть 3 типа заголовков:
● win32a — это базовый заголовок
● win32ax — этот заголовок расширен; у него есть макросы для эмуляции синтаксиса MASM высокого уровня
● win32axp — этот заголовок расширен; в нем есть макросы для эмуляции синтаксиса MASM высокого уровня, а также выполняется проверка параметров.
А как насчет заголовков и библиотек Win32?
Большинство структур и констант Win32 присутствует в заголовках FASM.
Вам придется добавлять недостающие вручную (но, как всегда, лучше делать это в отдельном включаемом файле).
Библиотеки импорта не нужны для того, чтобы FASM создал раздел импорта.
Существует макрос «import», используемый для создания раздела импорта, которому требуются только имена dll и имена функций для импорта. Раздел INCLUDE содержит импорт для наиболее часто используемых dll, отсутствующие можно создать вручную или с помощью таких инструментов, как «Сканер внешних функций» от Vortex, который автоматически создает точный импорт для исходного кода.
А как насчет ресурсов?
Есть два способа включения ресурсов в приложение: раздел ресурсов может быть построен из существующего res-файла, созданного внешним rc-компилятором, или с использованием собственных макросов fasm для создания ресурсов.
Использование этих макросов не сложнее, чем ручное редактирование rc-файла, но при построении диалоговых окон возникает небольшая трудность; их легче построить в визуальном режиме …
В качестве обходного пути я написал конвертер, который извлекает диалоги из rc-файла и строит аналогичные включения в формате fasm.Так что это больше не должно быть проблемой …
Как насчет поддержки UNICODE?
FASM поддерживает UNICODE: просто включите «win32 w *» вместо «win32 a *».
Используйте « du » для определения строк UNICODE:
du «Эта строка закодирована как широкий символ.», 0
Вы можете использовать неанглийские символы в строках UNICODE, включив соответствующий файл из папки ENCODE , который соответствует кодовой странице используемого языка.
Какой линкер мне нужен для FASM?
FASM создает приложения многих форматов напрямую, без компоновщика. Если вы хотите использовать компоновщик для объединения с другими библиотеками или объектами, вы можете использовать формат вывода объекта MS COFF с последующей компоновкой с помощью компоновщика MASM, POLINK или другого совместимого. Это также может быть полезно для отладки сложных проектов, поскольку FASM не выдает символьной информации для отладчика.
Есть ли в FASM что-то уникальное, чего не могут сделать другие сборщики?
FASM может включать внешние двоичные файлы непосредственно в исходный код с помощью директивы «файл».Вы можете указать смещение во включенном файле и сколько байтов включить.
Кроме сборки исходного кода, это позволяет вам создавать макросы перекодирования для символов, обеспечивать разделение, склейку, исправление внешних файлов напрямую с помощью fasm и т. Д.
Исходный код в таких случаях становится своего рода «скриптом задачи».
Вы можете установить любое начальное смещение или не устанавливать его вообще (эквивалент 0) и начать код — вы сразу получите двоичный файл с вашим кодом, без дополнительных инструментов, таких как exe2bin: очень удобно для разработчиков ОС, которые хотят загрузить код по известному адресу из двоичного файла без заголовков.
Поддерживает ли FASM макросы?
FASM имеет отличную поддержку макросов. Макросы в FASM способны генерировать сложный код / данные с циклическим циклом, повторением и т. Д.
Единственным недостатком макросов FASM является то, что они не возвращают значение, но когда это необходимо, можно эмулировать операцию.
Какова лицензионная политика FASM?
В настоящее время лицензия FASM позволяет не только бесплатно использовать FASM, но и создавать коммерческие приложения.Для получения дополнительной информации обратитесь к файлу LICENSE.TXT , включенному в пакет FASM.
Можно ли использовать FASM вместе с WinAsm Studio?
Да. Надстройка FASM добавляет полную поддержку для создания приложений с помощью fasm, включая сканирование для импорта и преобразование диалогов в формат fasm. Надстройка FASM написана на fasm.
Где взять все необходимое для начала работы с FASM?
● Сам FASM можно загрузить из раздела загрузок на домашней странице Flat Assembler.
● Все необходимые утилиты для использования FASM вместе с WinAsm Studio можно загрузить из раздела Support for other Assemblers здесь, на winasm.org.
● Сканер импорта можно загрузить с домашней страницы Vortex или из раздела MASM Tools здесь, на winasm.org.
Дополнительные ссылки
● Запись о Flat Assembler в Википедии
● FASMLIB, переносимая библиотека для 32-битного языка ассемблера x86 .
Вы можете загрузить файл справки «Быстрый запуск с FASM из WinAsm Studio» и дать или прочитать комментариев к статье Что такое FASM .
Прочие сборщики
Есть и другие ассемблеры с различными интересными и выдающимися особенностями.
что также может вас заинтересовать.
Примечание
Они могут находиться на разных стадиях разработки, а могут быть
неклассический / высокий уровень / что угодно еще.
AS86 — это ассемблер 80×86 (16- и 32-разрядный) со встроенной поддержкой макросов.Он имеет в основном Intel-синтаксис, хотя и немного отличается в отношении режимов адресации.
Некоторое время назад он использовался в нескольких проектах, в том числе в ядре Linux,
но со временем большинство этих проектов перешли на GAS или NASM. AFAIK, только
ELKS продолжает его использовать.
AS86 можно найти на
http://www.debath.co.uk/dev86/, в пакете bin86 с компоновщиком (ld86),
или как отдельный архив. Документация доступна как справочная страница и как.doc.
из исходного пакета. В случае сомнений исходный код часто оказывается хорошим
док: хотя это не очень хорошо прокомментировано, стиль программирования
простой.AS86 является частью ряда дистрибутивов BSD и Linux.
Примечание
AS86 — это в первую очередь 16-битный ассемблер.
Использование AS86 с BCC
Вот запись GNU Makefile для использования BCC для преобразования
.s
asm в оба объекта a.out .o
и .l
перечисление:
% .o% .l:% .s bcc -3 -G -c -A-d -A-l -A $ *. l -o $ *. o $ <
Снимите % .l
, -A-l
и
-A $ *. L
, если вам не нужен какой-либо список.Если ты чего-то хочешь
кроме a.out, вы можете изучить документы BCC о других поддерживаемых форматах,
и / или используйте утилиту objcopy из пакета GNU binutils.
YASM - это полная переработка ассемблера NASM под «новой» лицензией BSD.
Он разработан с нуля, чтобы можно было использовать несколько синтаксисов.
поддерживается (например, NASM, TASM, GAS и т. д.) в дополнение к нескольким объектам вывода
форматы, включая COFF, Win32 и Mach-O. Еще один основной модуль комбинезона
design - это модуль оптимизатора.
FASM (плоский ассемблер) - это быстрый и эффективный ассемблер 80x86, работающий в
«плоский реальный режим». В отличие от многих других ассемблеров 80x86, FASM требует только
исходный код для включения действительно необходимой информации. Это написано само по себе
и очень маленький и быстрый. Он работает под DOS / Windows / Linux и может производить плоские
двоичный, вывод DOS EXE, Win32 PE, COFF и Linux ELF. Видеть
http://flatassembler.net.
osimpa - ассемблер для процессоров Intel 80386 и последующих, написанных
полностью в оболочке интерпретатора команд GNU Bash.Предшественник osimpa
было обманом. osimpa значительно очищен, может создавать полезные исполняемые файлы Linux ELF,
и имеет различные HLL-подобные расширения и удобные для программиста команды.
Он (конечно) медленнее, чем другие ассемблеры. Он имеет собственный синтаксис (и использует
собственные имена для кодов операций x86) Прилагается довольно хорошая документация. Проверь это
вне:
ftp://linux01.gwdg.de/pub/cLIeNUX/interim/ (Доступ - это пароль
контролируется). Вы, вероятно, не будете использовать его регулярно, но, по крайней мере, он
заслуживает вашего интереса как интересная идея.
Aasm - это продвинутый ассемблер, предназначенный для поддержки нескольких целевых архитектур.
Он был разработан таким образом, чтобы его можно было легко расширить, и его следует рассматривать как хороший
альтернатива монолитной разработке ассемблера для каждого нового целевого процессора
и двоичные форматы файлов.
Aasm должен упростить программирование на ассемблере для разработчика, предоставляя
набор расширенных функций, включая области символов, механизм выражений,
поддержка больших целых чисел, возможности макросов, многочисленные и точные предупреждающие сообщения.Его динамическая модульная архитектура позволяет Aasm расширять набор функций.
с плагинами, используя преимущества динамических библиотек.
Модуль ввода поддерживает синтаксис Intel (например, nasm, tasm, masm и т. Д.).
Модуль ассемблера x86 поддерживает все коды операций до P6, включая MMX, SSE.
и 3DNow! расширения. Ассемблерные модули F-CPU и SPARC находятся в стадии разработки.
Доступны несколько модулей вывода для ELF, COFF, IntelHex и raw binary.
форматы.
http: //savannah.nongnu.org / projects / aasm /
Table Driven Assembler (TDASM) - это бесплатная портативная версия .
кросс-ассемблер для любого языка ассемблера. Должна быть возможность использовать
это как компилятор для любого целевого микропроцессора с использованием таблицы, которая определяет
процесс компиляции.
Это доступно из
http://www.penguin.cz/~niki/tdasm/ но похоже, что это уже не
активно поддерживается.
HLA - это H igh L evel
A язык сборки.Он использует язык высокого уровня, например
синтаксис (аналогичный Pascal, C / C ++ и другим HLL) для объявлений переменных,
объявления процедур и вызовы процедур. Использует модифицированную сборку
синтаксис языка для стандартных машинных инструкций. Он также предоставляет несколько
структуры управления стилями языка высокого уровня (if, while, repeat..until и т. д.)
которые помогут вам написать гораздо более читаемый код.
HLA бесплатен и поставляется с исходным кодом, доступны версии для Linux и Win32. На Win32
вам нужен MASM и 32-битная версия MS-link на Win32, на Linux вам нужен GAS,
потому что HLA производит указанный код ассемблера и использует этот ассемблер для окончательного
сборка и компоновка.
TALC - еще один бесплатный
Компилятор на основе MASM / Win32 (правда, он поддерживает вывод в формате ELF?).
TAL означает T yped A ssembly.
L англ. Расширяет традиционную нетипизированную сборку
языки с аннотациями набора текста, примитивами управления памятью и звуком
набор правил набора текста, чтобы гарантировать безопасность памяти, безопасность потока управления и
безопасность типов программ TAL. Более того, типизирующие конструкции выразительны.
достаточно для кодирования большинства функций программирования на исходном языке, включая записи
и структуры, массивы, высшие и полиморфные функции, исключения,
абстрактные типы данных, подтипы и модули.Не менее важно, что TAL - это
достаточно гибкий, чтобы допускать множество оптимизаций компилятора низкого уровня. Вследствие этого,
TAL - идеальная целевая платформа для компиляторов, ориентированных на тип, которые хотят
создавать проверяемый безопасный код для использования в защищенных мобильных кодовых приложениях или
расширяемые ядра операционной системы.
Free Pascal имеет внутреннюю
32-битный ассемблер (на основе таблиц NASM) и переключаемый выход, который позволяет:
Выводы MASM и TASM не так хорошо отлажены, как два других, но могут быть
иногда бывает удобно.
Внешний вид ассемблера основан на внутреннем BASM Turbo Pascal, и
IDE поддерживает аналогичную подсветку, а FPC может полностью интегрироваться с gcc
(на уровне C, а не C ++).
Используя фиктивный RTL, можно даже создавать программы на чистом ассемблере.
Win32Forth - это бесплатная 32-разрядная система ANS FORTH, которая
успешно работает под Win32s, Win95, Win / NT. Включает бесплатный 32-битный
ассемблер (префиксный или постфиксный синтаксис), интегрированный в рефлексивный
Четвертый язык.Макрообработка выполняется с полной мощностью отражающего
язык FORTH; однако единственными поддерживаемыми контекстами ввода и вывода являются
Win32 для себя (дамп файла .obj
нельзя, но можно
добавляйте эту функцию сами, конечно). Найдите это на
ftp://ftp.forth.org/pub/Forth/Compilers/native/windows/Win32For/.
Terse - это инструмент программирования, который
предоставляет THE самый компактный синтаксис ассемблера для x86
семья! Однако это злая проприетарная программа. Говорят, что был
проект для бесплатного клона где-то, который был заброшен из-за бесполезных отговорок
что синтаксис будет принадлежать первоначальному автору.Таким образом, если вы ищете
для отличного программного проекта, связанного с взломом сборок, я приглашаю вас
разработайте интерфейс для NASM с кратким синтаксисом, если вам нравится этот синтаксис.
Как интересное историческое замечание, на
comp.compilers,
1999/07/11 19:36:51, модератор написал:
«Нет причин, по которым ассемблеры должны иметь ужасный синтаксис. Около
30 лет назад я использовал PL360 Никлауса Вирта, который в основном был S / 360
ассемблер с синтаксисом Algol и небольшим синтаксическим сахаром, вроде цикла while
, который превратился в очевидные ответвления.Это действительно был ассемблер
, например, вам приходилось записывать свои выражения с явным присвоением
значений регистрам, но это было приятно. Вирт использовал его для записи
Algol W, небольшого быстрого подмножества Algol, предшественника
Pascal. Как это часто бывает, Algol W на
значительно лучше многих своих преемников. -Иоанн
Несвободные и / или не 32-битные ассемблеры x86
Вы можете найти о них больше, а также основы сборки x86.
программирование, в
Часто задаваемые вопросы по сборке x86 от Raymond Moon.
Обратите внимание, что все ассемблеры на основе DOS должны работать внутри эмулятора Linux DOS,
а также другие подобные эмуляторы, так что если у вас уже есть один, вы можете
до сих пор используйте его в реальной ОС. Последние ассемблеры на базе DOS также поддерживают COFF.
и / или другие форматы объектных файлов, поддерживаемые библиотекой GNU BFD,
так что вы можете использовать их вместе со своими бесплатными 32-битными инструментами, возможно, используя
GNU objcopy (часть binutils) в качестве фильтра преобразования.
.