Кто-то может объяснить эти немного строк MSIL?

Если вы используете vivo / honor / oppo и т. Д., Ваши службы будут убиты, как только ваше приложение будет закрыто.

5
задан Nathan Kleyn 13 April 2013 в 21:04
поделиться

2 ответа

Если вы откроете эту функцию в отладчике с кодом, скомпилированным в режиме отладки:

bool foo(string arg)
{
    return bar(arg);
}

Вы можете установить 3 точки останова:

  1. На открывающей скобке функции.
  2. В строке «возврата».
  3. В закрывающей фигурной скобке функции.

Установка точки останова на открывающей фигурной скобке означает «прерывание при вызове этой функции». Вот почему в начале метода есть инструкция о запрете операций. Когда точка останова устанавливается на открывающей скобке, отладчик фактически устанавливает ее на закрывающую скобку.

Установка точки останова на закрывающей скобке означает «прерывание при выходе из этой функции». Для того, чтобы это произошло, функция должна иметь единственную инструкцию возврата в ее IL, где может быть установлена ​​точка останова. Компилятор позволяет это, используя временную переменную для хранения возвращаемого значения, и преобразование

return retVal;

в

$retTmp = retVal;
goto exit;

с последующим внедрением следующего кода в конец метода:

exit:
return $ret;

Кроме того, в режиме отладки компиляторы тупо относятся к генерируемому ими коду. В основном они делают что-то вроде:

GenerateProlog();
foreach (var statement in statements)
{
    Generate(statement);
}
GenerateEpilog();

В вашем случае вы видите:

return foo(arg);

переводится в:

; //this is a no-op
bool retTemp = false;
retTemp = foo(arg);
goto exit;
exit:
return retTemp;

Если компилятор выполнял «оптимизацию скользящего окна», он мог бы посмотреть на этот код и понять, что есть некоторая избыточность. Однако компиляторы обычно этого не делают. не делайте этого в режиме отладки. Оптимизация компилятора может делать такие вещи, как удаление переменных и изменение порядка инструкций, что затрудняет отладку. Поскольку целью отладочной сборки является включение отладки, было бы нехорошо включать оптимизацию.

В сборке релиза код не будет выглядеть так. Который' s, потому что компилятор не вводит специальный код для включения точек останова в открывающих и закрывающих фигурных скобках, что оставляет только следующее для компиляции:

return bar(arg);

Это выглядит довольно просто.

Однако следует отметить одну вещь: что я не думаю, что компилятор C # делает много оптимизаций скользящего окна, даже в розничных сборках. Это потому, что большая часть этих оптимизаций зависит от базовой архитектуры процессора и выполняется JIT-компилятором. Выполнение оптимизаций, даже тех, которые не зависят от процессора, в компиляторе C # могут препятствовать способности JIT оптимизировать код (он ищет шаблоны, которые генерируются неоптимизированной генерацией кода, и если он видит сильно оптимизированный IL, он может получить смущенный). Поэтому обычно управляемые компиляторы кода этого не делают. Он делает некоторые "дорогие вещи"

7
ответ дан 13 December 2019 в 19:34
поделиться

Вы компилируете в режиме отладки или выпуска? В режиме выпуска я получаю:

.method private hidebysig static bool Test1(string arg) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: call bool FuncNameNotImportant::MethodNameNotImportant(string)
    L_0006: ret 
}

Ветвление, которое вы видите, вероятно, связано с поддержкой отладчика.

4
ответ дан 13 December 2019 в 19:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: