Online Compiler Nasm

extern scanf, printf section .rodata print_format db `%d`, 10, 0 scan_format db `%d %d`, 0 section .bss a resd 1 b resd 1 section .text global main main: and esp, ~15 push b push a push scan_format sub esp, 4 call scanf mov eax, [a] mov ecx, [b] add esp, 12 add eax, ecx push eax push print_format call printf add esp, 8 xor eax, eax ret
Этот код считывает два целых числа, складывает их и выводит результат. Однако в нём есть ошибка в работе со стеком при вызове scanf.

- При вызове scanf стек должен быть выровнен по 16 байт перед инструкцией call. После `and esp, ~15` выравнивание выполнено, но затем вы делаете три push (по 4 байта каждый) — это 12 байт, и стек становится не выровнен. Затем вы делаете `sub esp, 4`, что добавляет ещё 4 байта — итого 16 байт смещения, и выравнивание восстанавливается. Но после возврата из scanf вы делаете `add esp, 12`, что сдвигает стек неправильно, потому что вы не учли дополнительный `sub esp, 4`.

- Второй момент: после scanf вы читаете значения из памяти `[a]` и `[b]`, но перед этим вы не проверили, успешно ли выполнился scanf (возвращаемое значение в eax). Это не ошибка, но для учебного кода стоит помнить о проверке.