Как ассемблер включен в программу? - PullRequest
3 голосов
/ 20 июня 2009

Я читал во многих местах, что язык ассемблера обычно не используется для создания законченных программ, но используется другими программами для повышения эффективности определенных процедур, особенно тех, которые вызываются пару тысяч раз в секунду. Мне интересно, как маленькие кусочки ассемблерного кода включаются в большие программы.

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

  • Затем я подумал о встроенной сборке для Visual Studio, но это специфично для Microsoft, и, похоже, будет лучший способ.

Итак, как можно использовать небольшие куски кода сборки в более крупной программе без создания отдельных программ или использования встроенной сборки Visual Studio?

Ответы [ 4 ]

5 голосов
/ 20 июня 2009

Встроенная сборка не является специфической для Visual Studio - GCC также поддерживает ее. Встроенная сборка, как правило, является наиболее простым способом включения сборки в программу. Однако есть пара проблем - они могут сильно повлиять на переносимость вашего кода, и некоторые компиляторы не поддерживают его - например, компилятор Microsoft x64 не поддерживает его.

Для компиляторов, которые не поддерживают встроенную сборку или если вы хотите содержать весь машинный код, вы обычно разделяете части языка ассемблера на свои собственные файлы, предоставляя код сборки как функции, которые может вызывать ваш код C ++. Затем вы собираете и связываете их как часть сборки. Ваш компоновщик не заботится о том, какой язык использовался для генерации объектных файлов - он может собирать объектные файлы с нескольких языков в одну программу.

1 голос
/ 20 июня 2009

Затем я подумал о встроенной сборке для Visual Studio, но она специфична для Microsoft, и, похоже, есть лучший способ.

Каждый компилятор поддерживает некоторую форму встроенной сборки, хотя обычно немного по-разному.

Так что, если вам нужно использовать встроенную сборку, заключите каждый фрагмент в небольшую функцию. Затем вы можете без особых усилий переопределить эти функции при переносе на другой компилятор.

1 голос
/ 20 июня 2009

Вот пример (GCC):

__asm__ ("movl %eax, %ebx\n\t"
"movl $56, %esi\n\t"
"movl %ecx, $label(%edx,%ebx,$4)\n\t"
"movb %ah, (%ebx)");

В Microsoft Inline Assembly ключевое слово __asm, код сборки заключен в фигурные скобки, это не строка, а целевой регистр теперь слева.

Пример Microsoft:

int foo(void) {
  __asm{
   mov eax,100 ; Moves 100 into eax!
   leave
   ret
  };
}

Ссылки для получения дополнительной информации

Инструкции по сборке и справочная информация по сборке: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

Учебное пособие IBM, специфичное для x86: http://www.ibm.com/developerworks/linux/library/l-ia.html

0 голосов
/ 20 июня 2009

Для небольших кусочков кода, таких как внутренние циклы, это обычно делается с помощью встроенной сборки. И это определенно не специфично для Microsoft! (GCC и почти все современные компиляторы тоже поддерживают его, хотя и с разными вариациями синтаксиса).

Для больших кусков кода (например, загрузчик для операционной системы) он обычно помещается в отдельный исходный файл (так же, как вы используете несколько исходных файлов на каждом языке), а затем связывается с остальными программы с использованием компоновщика.

Имейте в виду, что сборка в основном используется в настоящее время только для ОС, потому что компиляторы теперь достаточно хороши, и это мало помогает в использовании их для внутренних циклов в таких вещах, как игры (и вовсе не переносится на разные архитектуры ). Он в основном используется для действительно низкоуровневых таких вещей, как аппаратные прерывания и настройка подкачки (виртуальной памяти).

...