Почему директива.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, а затем запускаю сгенерированный исполняемый файл.
2 ответа
Я думаю, что ваше замешательство связано с неправильным пониманием того, что .maxstack
на самом деле Это простая ошибка, потому что кажется, что это вызовет ошибку при выполнении. Удивительно, что эта конкретная директива на самом деле не имеет ничего общего с размером стека во время выполнения, вместо этого она специально используется во время проверки кода.
Из раздела III - раздел 1.7.4
Примечание: Maxstack связан с анализом программы, а не с размером стека во время выполнения. Он не определяет максимальный размер в байтах стекового фрейма, а скорее количество элементов, которые должны отслеживаться инструментом анализа.
Код становится не поддающимся проверке. В том же разделе отмечается, что любая соответствующая реализация не должна поддерживать метод с недопустимым значением максимального стека. Тем не менее, это не говорит о том, что он не должен, и совершенно ясно, что среда выполнения выполняет код. Так что, если это кажется безрезультатным, зачем вообще его беспокоить?
Хотите верьте, хотите нет, по умолчанию.NET Framework запускает непроверяемый код. Мне было действительно трудно понять, как включить проверку в.NET 4.0, но если вы включите CAS, ваша программа (с .maxstack 1
) перестанет работать с
Необработанное исключение: System.InvalidProgramException: Common Language Runtime обнаружил недопустимую программу. в основном ()
Учитывая это, не поддающийся проверке код не может работать в любой среде, которая не имеет полного доверия (как правило, сборки из Интернета). Если это не важно для вас, вы можете позволить ему быть недопустимым значением, и это действительно не будет иметь значения. Если сам код по-прежнему корректен, он будет работать нормально; конечно, если на самом деле есть проблема со стеком IL, он выдаст InvalidProgramException
,
Если я правильно помню, размер стека по умолчанию равен 8, если оператор опущен.