Команды call и callvirt в CLR. Какая разница?

Исходя из названия, callvirt каким-то образом связан с чем-то виртуальным, но впринципе то у этих двух команд идентичное ж значение, не так-ли? И первая и вторая в результате вызывает метод. Чем они отличаются?

Если можно, какой-то ресурс посоветуйте, где можно почитать про это...

"Инструкция call используется для вызова статических, экземплярных и виртуальных методов. Если с помощью этой инструкции вызывается статический метод, необходимо указать тип, в котором определяется метод. При вызове экземплярного или виртуального метода необходимо указать переменную, ссылающуюся на объект, причем в call подразумевается, что эта переменная не равна null. Иначе говоря, сам тип переменной указывает, в каком типе определен необходимый метод. Если в типе переменной метод не определен, проверяются базовые типы. Инструкция call часто служит для невиртуального вызова виртуального метода.

Инструкция callvirt используется только для вызова экземплярных и виртуальных (но не статических) методов. При вызове необходимо указать переменную, ссылающуюся на объект. Если с помощью этой инструкции вызывается невиртуальный экземплярный метод, тип переменной показывает, где определен необходимый метод. При использовании callvirt для вызова виртуального экземплярного метода CLR определяет настоящий тип объекта, на который ссылается переменная, и вызывает метод полиморфно. При компиляции такого вызова JIT-компилятор генерирует код для проверки значения переменной — если оно равно null, CLR сгенерирует исключение NullReferenceException. Из-за этой дополнительной проверки инструкция callvirt выполняется немного медленнее, чем call. Проверка на null выполняется даже при вызове невиртуального экземплярного метода." - Джеффри Рихтер, "CLR via C#"