Вставки Как скомпилировать asm, созданный GCC? Как скомпилировать файл asm
ассемблерные вставки в gcc (6)
Да, gcc также может скомпилировать исходный код сборки. Кроме того, вы можете ссылаться as на ассемблер. (gcc - это просто «драйверная» программа, которая использует эвристику для вызова компилятора C, компилятора C ++, ассемблера, компоновщика и т. д.).
Я играю с некоторым кодом asm, и что-то меня беспокоит.
Я скомпилирую это:
#include
с gcc file.c -S -o file.S это генерирует приятный маленький кусок кода asm:
Cstring LC0: .ascii "Hello World\0" .text .globl _main _main: LFB3: pushq %rbp LCFI0: movq %rsp, %rbp LCFI1: subq $16, %rsp LCFI2: movl %edi, -4(%rbp) movq %rsi, -16(%rbp) leaq LC0(%rip), %rdi call _puts movl $0, %eax leave ret LFE3: .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 .long L$set$0 LSCIE1: .long 0x0 .byte 0x1 .ascii "zR\0" .byte 0x1 .byte 0x78 .byte 0x10 .byte 0x1 .byte 0x10 .byte 0xc .byte 0x7 .byte 0x8 .byte 0x90 .byte 0x1 .align 3 LECIE1: .globl _main.eh _main.eh: LSFDE1: .set L$set$1,LEFDE1-LASFDE1 .long L$set$1 LASFDE1: .long LASFDE1-EH_frame1 .quad LFB3-. .set L$set$2,LFE3-LFB3 .quad L$set$2 .byte 0x0 .byte 0x4 .set L$set$3,LCFI0-LFB3 .long L$set$3 .byte 0xe .byte 0x10 .byte 0x86 .byte 0x2 .byte 0x4 .set L$set$4,LCFI1-LCFI0 .long L$set$4 .byte 0xd .byte 0x6 .align 3 LEFDE1: .subsections_via_symbols
Моя следующая проблема действительно, как я могу скомпилировать этот вывод, и могу ли я сделать GCC для этого?
Nasm -f bin -o 2_hello 2_hello.asm
Вы можете вставить код сборки в обычную C-программу. Вот хорошее introduction . Используя соответствующий синтаксис, вы также можете указать GCC, с которым хотите взаимодействовать с переменными, объявленными в C. В приведенной ниже программе указано gcc, что:
- eax должен быть foo
- ebx должен быть баром
- значение в eax должно храниться в foo после выполнения кода сборки
Int main(void) { int foo = 10, bar = 15; __asm__ __volatile__("addl %%ebx,%%eax" :"=a"(foo) :"a"(foo), "b"(bar)); printf("foo+bar=%d\n", foo); return 0; }
gcc может использовать файл сборки как входной сигнал и при необходимости активировать ассемблер. Однако есть тонкость:
- Если имя файла заканчивается на « .s » (строчные буквы), то gcc вызывает ассемблер.
- Если имя файла заканчивается на « .S » (верхний регистр «S»), gcc применяет препроцессор C в исходном файле (то есть он распознает директивы, такие как #if и заменяет макросы), а затем вызывает ассемблер в результате.
Итак, на общей основе вы хотите сделать что-то вроде этого:
Gcc -S file.c -o file.s gcc -c file.s
Да, вы можете использовать gcc для компиляции вашего asm-кода. Используйте -c для компиляции следующим образом:
Gcc -c file.S -o file.o
Это даст файл объектного кода с именем file.o. Для вызова компоновщика выполните следующую команду.
Альтернативный компилятор ассемблера для х86. Ассемблер написан сам на себе имеет очень простой синтаксис. Позволяет создавать.com файл для ДОС. Поддерживает 32 разрядные режимы адресации и данных. Доступен вместе с исходным кодом.
Описание ассемблера.
- Ассемблер работает из командной строки. Входной файл должен иметь любое
имя с расширением:
- .xxx или любым другим - значения не имеет, главное чтобы оно было
Запуск на компиляцию:asm filename.ext. Результат - сообщение об ошибке в строке с № или filename.com / filename.obj
- Ассемблер создает только*.com файлы, *.exe не созжаются. Конечно.com файл имеет ограничение 64 кб. кода, однако вряд ли кто-нибудь напишет на ассемблере больше. Т.к. создаются только*.com файлы не надо думать о сегментах. Нет у ассемблера и компоновщика. Он просто не нужен.
- Ассемблер позволяет создавать модули*.obj , которые потом можно внедрять в код программ, как внешние подключаемые модули – подпрограммы.
- Команды можно записывать в строчку разделяя их";"
- Разделительные пробелы между командами и операндами вставлятьНЕ обязательно. Система команд х86 позволяет интерпретировать их и без пробелов.
- Поскольку командаMOV встречается в программах на ассемблере наиболее часто ее имя писать не обязательно.
- Регистр не имеет значения. Компилятор одинаково интерпретирует строки
MOV AH,09
movah,9
aH,9 - Ассемблер понимает 32 битные режимы адресации и автоматически вставляет префискы 32 битного адреса и данных, 66 и 67, когда это необходимо
- Cистемa сообщения об ошибках довольно слабая. Сообщениеошибка в строке N следует понимать, какошибка в строке N +/- 1.
- Команды математического сопроцессораНЕ поддерживаются .
- * Коментарии вставляются между парными*
- Основными синтаксическими элементами являются символы"="
и " () "
- =Label= Вводит меку адреса.
- (Label) вставляет значение адреса в код.
Метки чувствительны к регистру.
Дальше рассмотрим пример HelloWorld .
* Кстати
комментарии вставляются между парными звездочками
Пример1 "Hello World" выводит на экран надпись.*
JMPS(S)
=A1= "Hello World !"
=A2= 0A
=S= AX,B800;ES,AX;AX,3;INT10
CX,(A2-A1);SI,(A1);DI,500
AH,[(A2)]
=L= LODSB;STOSW;LOOP(L)
RET
JMP - кодирует длинный переход в пределах сегмента.
JMPS - короткий +/- 127 байт.
Со второй строкой все понятно. Третья строка:
По адресу (А2) в памяти ЭВМ размещается байт равный 0А.
Т.е.
Хотите зарезервировать в памяти байт - пищите так:
=vmode= 00 или =adr= 12
Надо выделить два байта пишите:
=X= 0000 или wo0
или
=Y=
wo
something
for example rd ptr
1234
Есть три ключевых слова определяющих размер.
- by- BYTE (8)
- wo - WORD (16)
- dw - DWORD (32)
ассемблер проигнорирует все что встретит между этими буквами и
первой цифрой.
Нужен массив из двойных слов -
пожалуйста:
=array= dw0;12345678;01234;dw12;...
Желаете иметь таблицу адресов
чего-нибудь - no problem:
=mytable= (adr1);(adr2);(adr3);dword(adr4)...
C адресами возможны следующие
манипуляции:
CX,(A2-A1) * В CX получается длина
строки(см пример)*
jmps (adr)+2;
mov ,(adr3-adr4)-5
В 386 процессоре появились команды
длинного условного перехода. Отличаются они от коротких так:
JZ (adr) - короткий
JZ
_N
(adr)
- длинный.
Префиксы "66" и "67" вставляются автоматически.
Префиксы сегментов надо использовать в следующем виде:
ES:
LODSB
или
ES:;LODSB
SS:;MOVAX,
Описание текстового макроса
Вывод листинга препроцессора в stdout
Определить размер стека (байт)
Имя исполняемого файла
Создание файла листинга
Создание map-файла
Имя объектного файла
Включение кода эмулятора сопроцессора 80x87
Включить ограниченную информацию броузера
Включить полную информацию броузера
Использовать соглашения вызова Pascal, C или Stdcall
Установить максимальную длину внешних имен
Добавить путь для inc-файлов
Опции командной строки компоновщика и подключаемые библиотеки
Не показывать баннерный текст компилятора
Листинг максимального формата
Включить в листинг синхронизацию
Листинг первого прохода
Длина строки листинга, символов: 60...255 или 0.
Не включать в листинг таблицу символов
Высота страницы листинга, строк: 10...255 или 0.
Текст подзаголовков листинга
Текст заголовка листига
Включить в листинг все фрагменты условной компиляции
Компилировать не-.asm файлы
То же, что /W0 /WX
Трактовать предупреждения как ошибки
Установить уровень предупреждеинй
Игнорировать путь, установленный переменной окружения INCLUDE
Включить отладочную информацию в виде номеров строк
Объявить все имена публичными
Включить полную отладочную информацию
Включить совместимость с MASM 5.10
Установить выравнивание структур
Выполнять только проверку синтаксиса
Типовая командная строка для этапа отладки (активен проект Win32 Debug) имеет вид: