Q
Size: a a a
Q
E
mov ebx, 2Потом ты вызываешь какую-то функцию, она возвращает результат в EAX:
add ebx, ecx
jc ...
call some_funcОна не сохраняет регистры, и делает что-то с EBX и ECX:
some_func:После того, как фунцкия вернётся, ты продолжаешь работать с регистрами:
...
xor ebx, ebx
mov ecx, ebx
...
ret
add ebx, ecxА вот беда - функция не сделала:
push ebxПоэтому теперь в ECX и EBX у тебя нули, и всё сломалось.
push ecx
...
xor ebx, ebx
mov ecx, ebx
...
pop ecx
pop ebx
ret
Q
Q
E
push eaxКак думаешь, красивый? Хотя, сколько не некрасивый, а неудобный (ну и неоптимизированный). Поэтому все пришли к выводу, что намного удобнее, и лушче - переносить сохранение регистров внутрь функции
push ebx
push ecx
push data ; arg3
push ecx ; arg2
push 1 ; arg1
call func
pop ecx
pop ebx
pop eax
Q
A
A
Q
E
push ebxА на деле окажется, что функция изменяет только один EBX, вот и потратил скорость и размер на лишние push/pop
push ecx
push esi
push edi
A
II
d
楽
d
E
d
Q
E
d