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). Это не ошибка, но для учебного кода стоит помнить о проверке.