Почему опция .MaxStack необязательна в коде MSIL?

Я изучаю язык ассемблера в свободное время. Может кто-нибудь объяснить, почему .maxstack представляется необязательным в этой программе. Я попытался найти ответ в Интернете и в моей книге без такой удачи, то есть программа будет компилироваться и запускаться с помощью .Maxstack:

//Add.il
//Add Two Numbers

.assembly extern mscorlib {}

.assembly Add
{
    .ver 1:0:1:0
}
.module add.exe

.method static void main() cil managed
{
    //.maxstack 2
    .entrypoint

    ldstr "The sum of 50 and 30 is = "
    call void [mscorlib]System.Console::Write (string)

    ldc.i4.s 50
    ldc.i4 30    
    add
    call void [mscorlib]System.Console::Write (int32)
    ret
}

Я компилирую программу в командной строке с помощью инструмента ILASM, а затем запускаю сгенерированный исполняемый файл.

Ответ 1

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

Из раздела III - Раздел 1.7.4

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

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

Верьте или нет, по умолчанию .NET Framework запускает непроверяемый код. Мне было сложно понять, как включить проверку в .NET 4.0, но если вы включите CAS, ваша программа (с помощью .maxstack 1) перестанет работать с

Необработанное исключение: System.InvalidProgramException: Common Language Runtime обнаружила недопустимую программу.   на main()

Помня об этом, непроверяемый код не может работать в любой среде, которая не имеет полного доверия (как правило, сборок из Интернета). Если это не важно для вас, вы можете позволить ему быть недопустимым значением, и это действительно не изменит ситуацию. Если сам код по-прежнему прав, он будет работать нормально; конечно, если есть проблема с IL-стекем, он будет бросать InvalidProgramException.

Ответ 2

Если я правильно помню, размер стека по умолчанию равен 8, если инструкция опущена.