Вы смотрите на детали реализации: они, как правило, не совпадают со спецификацией ECMA по многим возможным причинам (например, простота реализации, совместное использование кода, предоставление дополнительной семантики, прогнозирование на будущее, оптимизация и т. Д.).
В данном конкретном случае есть несколько соображений.
Mono выполняет обработку исключений на основе представления состояния процессора, называемого MonoContext: поскольку эта структура используется и в других местах, она содержит все соответствующие регистры, даже если некоторые из них могут не понадобиться в некоторых особых случаях. В частности, обработка исключений может быть инициирована также из исключения процессора, где все регистры должны быть восстановлены, поэтому все они собираются.
Кто-то уже заметил, что контекст используется и для отладчика.
Рассмотрим также случай с методом try / catch, в котором catch является простой локальной установкой var. Теперь расширенный распределитель регистров может поместить локальную переменную, которая используется как перед броском (обратите внимание, что бросок может быть неявным, как нулевая ссылка, так что обрабатывается путем исключения из процессора), так и после перехвата в регистре, подобном edx. Если вы не сохраните все регистры в точке выброса / исключения, вы испортили состояние программы, так как edx перезаписывается во время обработки исключений.
В качестве последнего комментария: вы обеспокоены тем, что сохранение нескольких лишних регистров тратит впустую циклы процессора? Если вы действительно посчитаете потраченные циклы, то они полностью в шуме относительно всего, что должно произойти во время обработки исключений.