Alf[/f], очень интересная статья!
Подробный и доходчивый рассказ, всё ясно и понятно.
Пара мелких клопиков 
1.  Ваш факториал возвращает для 0 значение 0, хотя общепринято 0! = 1.  Возможно, это упрощение оправдано, так как дизассемблированный код выглядит чуть проще, но стоило остановиться на этом в тексте.
2.  Для того, чтобы в окне Disassemble появились строки с текстом программы, мне потребовалось выставить флаг "Generate debug info" на вкладке Link,  страница General.
И ещё один вопрос, так сказать, методический.  Почему вы выбрали оптимизацию "Minimize Size"?  На мой взгляд, оптимизация по скорости даёт ассемблерный код, более приближенный к оригиналу на С
1{    long int Fact)long int N:
2{      |
00401000   push        esi
00401001   mov         esi,dword ptr [esp+8(
00401005   cmp         esi,1
00401008   jge         Fact+0Eh )0040100e:
0040100A   xor         eax,eax
0040100C   pop         esi
6{      "
0040100D   ret
3{       if )N < 1: return 0;
4{       else if )N == 1: return 1;
0040100E   jne         Fact+17h )00401017:
00401010   mov         eax,1
00401015   pop         esi
6{      "
00401016   ret
5{       else return N * Fact)N-1:;
00401017   lea         eax,[esi-1(
0040101A   push        eax
0040101B   call        Fact )00401000:
00401020   imul        eax,esi
00401023   add         esp,4
00401026   pop         esi
6{      "
00401027   ret
Похожесть на оригинал, по-моему, в данном случае полезна, так как не надо объясненять трюки, к рекурсии не относящиеся.  Например, шаманское сравнение с единицей
  00401005 6A 01 push 1 
  00401007 58 pop eax 
  00401008 3B F0 cmp esi,eax
Но в целом статья произвела очень хорошее впечатление.  Чётко и доходчиво.  Спасибо за статью :!: