2010-06-20 3 views
5

Я понимаю, что компилятор преобразует язык высокого уровня в машинный код. У меня вопрос о том, использует ли компилятор (например, VC++) ассемблер? Я помню, что видел код сборки, всякий раз, когда происходит сбой или что-то в этом роде.Есть ли у компилятора ассемблер?

+1

Ассемблер - это всего лишь взаимное сопоставление машинных команд (бит кода) с некоторыми мнемоническими кодами (например, 'mov ax, bx'). Вот почему вы можете переводить коды сборки на машинные коды и обратно без каких-либо больших усилий. Компилятор выполняет гораздо более сложную работу, и между исходным кодом и созданным кодом не существует взаимно однозначного отношения (независимо от того, является ли он прямым машинным кодом или инструкциями по сборке). Вот почему вы обычно не можете видеть исходный код из двоичного кода. – ony

+0

ony: это относится к несимметричному ассемблеру без макросов. Но даже выход ГАЗа символичен. –

ответ

5

Это зависит от компилятора; многие компиляторы могут скомпилироваться для сборки. Например, если вы передаете флаг «-s» для GCC, как:

gcc -S -o test.S test.c 

Это будет выводить узел для файла test.c в файл test.s, которые вы можете посмотреть. (Я рекомендую использовать -O0, если вы попытаетесь прочитать сборку, потому что оптимизация компилятора там, скорее всего, смутит вас от вас).

Поскольку вы упомянули Visual C++ в своем вопросе, Павел Диксон указывает ниже, что Visual C++ использует the /FA flag для достижения того же.

+1

. Ну, на самом деле, в основном GCC делает это :-) Большинство коммерческих имеют встроенные функции, чтобы избежать медленного генерации/репарация текстового шага, только с возможностью генерации ассемблера, если это необходимо. –

1

Компилятор переходит непосредственно к машинным кодам.

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

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

+0

Неправильно .... Я мог запрограммировать компилятор, который выводит только источник сборки, который будет собран отдельно от ассемблера ... Более того, компилятор вряд ли идет так _directly_ в машинный код ... внутреннее представление (отличное от целевой машинной трески) кода (!) может быть очень полезно для оптимизации и так далее ... нормально, все, вероятно, скрыто, но «_directly_» слишком сильно! : D – ShinTakezou

+0

Вы могли бы, но ответить на вопрос OP. Visual Studio не выводит ассемблер, а затем вызывает MASM для генерации exe. –

1

Большинство компиляторов будут иметь возможность просмотреть сборку листинг

  • VC может быть сказано, чтобы выводить ассемблер листинг с /FA
  • с GCC, используйте переключатель -S
0

A компилятор переводит язык программирования высокого уровня на язык более низкого уровня (в виде машинного кода, сборки или даже другого языка высокого уровня, например, от Vala до C или от uC++ до C++).

Я не знаю о VC++, но большинство компиляторов, так как GNU GCC не включает в себя Assembler, но вызывает внешнюю программу Assembler (как NASM или GNU AS).

Cheers

3

В общем, компилятор переводит один язык в другой. Большинство компиляторов целевого машинного кода; здесь наиболее распространенные способы сделать это в порядке от наименьшего уровня до самого высокого уровня:

  1. Производите машинный код напрямую, включая обратные концы для каждого набора команд.
  2. Производите ассемблерный язык, который передается внешнему ассемблеру. Это то, что делает gcc. В конце концов, почему бы не использовать существующие ассемблеры? Генерирование опкодов напрямую - это боль.
  3. Создайте низкоуровневую промежуточную форму кода, например LLVM bytecode, которая преобразуется в машинный код. LLVM - это находка для авторов-компиляторов, поскольку он обрабатывает огромное количество оптимизаций и поддерживает множество обратных ссылок, позволяя вам писать на более высоком уровне, чем сборка.
  4. Преобразуйте код на такой язык, как C, а затем передайте его другому компилятору. Facebook does this to PHP: они скомпилируют его на C++, а затем используют gcc для компиляции сборки, которая собирается GNU GNU как родной.

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

Смежные вопросы