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
Но в целом статья произвела очень хорошее впечатление. Чётко и доходчиво. Спасибо за статью :!: