То, что вы видите, когда используете Debug + Windows + Разборка при отладке программы на C #, является хорошим руководством для этих условий.Вот его аннотированная версия, когда я компилирую программу «hello world», написанную на C #, в конфигурации выпуска с включенной оптимизацией JIT:
static void Main(string[] args) {
Console.WriteLine("Hello world");
00000000 55 push ebp ; save stack frame pointer
00000001 8B EC mov ebp,esp ; setup current frame
00000003 E8 30 BE 03 6F call 6F03BE38 ; Console.Out property getter
00000008 8B C8 mov ecx,eax ; setup "this"
0000000a 8B 15 88 20 BD 02 mov edx,dword ptr ds:[02BD2088h] ; arg = "Hello world"
00000010 8B 01 mov eax,dword ptr [ecx] ; TextWriter reference
00000012 FF 90 D8 00 00 00 call dword ptr [eax+000000D8h] ; TextWriter.WriteLine()
00000018 5D pop ebp ; restore stack frame pointer
}
00000019 C3 ret ; done, return
Щелкните правой кнопкой мыши в окне и отметьте «Показать байты кода», чтобыполучить аналогичный дисплей.
В столбце слева указан адрес машинного кода.Его значение подделывается отладчиком, код фактически находится где-то еще.Но это может быть где угодно, в зависимости от местоположения, выбранного компилятором JIT, поэтому отладчик просто начинает нумерацию адресов с 0 в начале метода.
Второй столбец - машинный код .Фактические 1 и 0, которые выполняет ЦП.Машинный код, как здесь, обычно отображается в шестнадцатеричном виде.Возможно, показательно, что 0x8B выбирает инструкцию MOV, дополнительные байты предназначены для того, чтобы точно указать процессору, что нужно переместить.Также обратите внимание на две разновидности инструкции CALL: 0xE8 - это прямой вызов, 0xFF - это команда косвенного вызова.
Третий столбец - это код сборки .Сборка - это простой язык, разработанный для облегчения написания машинного кода.Это сравнивается с C #, компилируемым в IL.Компилятор, используемый для перевода ассемблерного кода, называется «ассемблер».Возможно, на вашей машине установлен ассемблер Microsoft, его исполняемый файл называется ml.exe, ml64.exe для 64-битной версии.Существует две распространенные версии языков ассемблера.То, что вы видите, это то, что Intel и AMD используют.В мире открытого исходного кода сборка в нотации AT & T распространена.Синтаксис языка сильно зависит от типа процессора, для которого он был написан, язык ассемблера для PowerPC очень отличается.
Хорошо, это касается двух терминов в вашем вопросе.«Нативный код» - это нечеткий термин, он нередко используется для описания кода на неуправляемом языке.Возможно, поучительно посмотреть, какой машинный код генерируется компилятором Си.Это версия 'hello world' на C:
int _tmain(int argc, _TCHAR* argv[])
{
00401010 55 push ebp
00401011 8B EC mov ebp,esp
printf("Hello world");
00401013 68 6C 6C 45 00 push offset ___xt_z+128h (456C6Ch)
00401018 E8 13 00 00 00 call printf (401030h)
0040101D 83 C4 04 add esp,4
return 0;
00401020 33 C0 xor eax,eax
}
00401022 5D pop ebp
00401023 C3 ret
Я не аннотировал ее, в основном потому, что она очень похожа на машинный код, сгенерированный программой C #.Вызов функции printf () сильно отличается от вызова Console.WriteLine (), но все остальное примерно одинаково.Также обратите внимание, что отладчик теперь генерирует адрес реального машинного кода и что он немного умнее с символами.Побочный эффект генерации отладочной информации после генерации машинного кода, как это часто делают неуправляемые компиляторы.Следует также упомянуть, что я отключил несколько параметров оптимизации машинного кода, чтобы машинный код выглядел одинаково.Компиляторы C / C ++ имеют гораздо больше времени для оптимизации кода, результат часто трудно интерпретировать.И очень трудно отлаживать.
Ключевым моментом здесь является то, что очень мало различий между машинным кодом, сгенерированным из управляемого языка компилятором JIT, и машинным кодом, сгенерированнымкомпилятор нативного кода.Что является основной причиной, по которой язык C # может конкурировать с компилятором нативного кода.Единственная реальная разница между ними - вызовы функций поддержки.Многие из которых реализованы в CLR.И это вращается вокруг сборщика мусора.