2017-01-31 3 views
0

В C или C++ вы можете реализовать встроенные инструкции по сборке, выполнив следующие действия:GCC Инлайн Ассамблея Binary

asm("assembly code"); 

или

__asm__ ("assembly code"); 

Пример:

asm("movl %ebx, %eax"); /* moves the contents of ebx register to eax */ 
__asm__("movb %ch, (%ebx)"); /* moves the byte from ch to the memory pointed by ebx */ 

И тогда вам может генерировать взаимодействие для обмена значениями между вашим ассемблерным кодом и вашими переменными C/C++: Подробнее об этом here.

Мой вопрос: Является ли каждая инструкция встроенной сборки непосредственно переведенной в ее двоичную копию компилятором? Или это просто своего рода «Эмуляция»? Все это сводилось к тому, что я хотел знать, действительно ли вы обращаетесь к регистрам процессора или все данные, обрабатываемые в коде, хранятся в стеке, эмулируя инструкции сборки. Извините, если вопрос немой.

+4

Встроенный ассемблер GCC выполняет простую замену (если используется расширенный шаблон ассемблера), но выводит инструкции в одном операторе _ASM_, как и в коде. Так что да, после компиляции в код он будет использовать реальные регистры. Это, конечно, предполагает, что программа не запускается в эмуляторе. –

+1

спасибо, просто у меня возникло сомнение – J3STER

ответ

0

При использовании '__asm__' или 'ASM' ключевые слова, GCC/G ++ разбирает строку в инструкции по сборке. Если вы используете «расширенная сборка», то есть когда вы включаете двоеточия после строки, чтобы ваши переменные взаимодействовали с регистрами ' регистров, встроенный ассемблер выполняет простую замену, как и в следующий пример:


__asm__ ("\
добавить% EBX,% EAX; \
мов% EBX,% ECX; \
": "= с" (output_variable): " b "(first_operand)," a "(second_operand):/* Здесь ничего не нужно * /);

Обратите внимание на обратную косую черту в конце каждой конвейерной линии. Чтобы избежать прыжка линии, нужно использовать одну пару котировок для englobe всего кода сборки. Кроме того, для того, чтобы помочь рядным сборкам парсера, каждая инструкция сборки должна заканчиваться точкой с запятой


После обучения/с между двойными кавычками, вы можете добавить три двоеточия, между двумя первыми, вам объявите переменные, которые будут получать результат. Примечание: «= c» (output_variable) означает, что значение, сохраненное в регистре ecx, будет перенаправлено на переменную от ().

Между двумя последними двоеточиями вы объявляете переменные/значения, которые будут служить в качестве входных данных, поэтому в начале кода значение между скобками присваивается регистру, представленному буквой между кавычками (используйте comas для более чем одного ввода).

После последнего двоеточия, идет список списанных регистров. Однако это необязательно и бесполезно в данном конкретном случае. Подробнее о сборке GCC Inline Assembly here.

Итак, в заключение, исполнение выглядит следующим образом:

  • Замена входных значений, если таковые имеются, в соответствующие регистры
  • перевода из сборки в двоичном
  • выход нагрузки в присвоенных переменных , если

Поэтому короткий ответ был бы да, как только код будет скомпилирован в машинный язык, преобразование будет 1 на 1, как обычный ассемблер, и, следовательно, оно будет использовать реальные регистры.


+1

Я забыл сказать, что обратная косая черта в конце каждой конвейерной линии состоит в том, чтобы избежать скачка линии, чтобы использовать одну пару котировок. А также, каждая инструкция по сборке должна заканчиваться точкой с запятой, подумал, что это только поможет встроенному синтаксическому анализатору –

+0

спасибо !!! редактирование – J3STER

+1

Следует также указать, что ваш пример добавляет ebx в eax и сохраняет результат в eax. Вы перемещаете ebx в ecx, который фактически устанавливает ebx в содержимое first_operand, а не на добавленные значения. –