У вас есть следующие проблемы:
- Вы забыли
pop rbp
. - Вы неправильно выровняете стек, который должен быть выровнен на 16 байт.
- Выне заканчивайте нулем вашу строку формата (спасибо Павлу за указание на это).
- Вы используете
%d
, который записывает 4-байтовое целое число, но вы выделили только 2 байта с dw
. - Рекомендуется выравнивать целые числа до 4 байтов.
Возможная фиксированная версия:
section .data
number dd 0
text db 'Put a number',10,0
scanform db '%d', 0
section .text
extern printf,scanf
global main
main:
push rbp
mov rbp,rsp
push rdi
push rsi
push rbx
push rbx ; for alignment
mov rdi,text
mov rax,0
call printf
mov rsi,number
mov rdi,scanform
mov rax,0
call scanf
pop rbx
pop rbx
pop rsi
pop rdi
pop rbp
ret
Так как rsi
и rdi
являются регистрами, сохраненными вызывающим абонентом, и rbx
не тронут, вы можете упростить код.Я также изменил на xor
обнуление и относительную адресацию следующим образом:
section .data
number dd 0
text db 'Put a number',10,0
scanform db '%d', 0
section .text
extern printf,scanf
global main
main:
push rbp
lea rdi, [rel text]
xor eax, eax
call printf
lea rsi, [rel number]
lea rdi, [rel scanform]
xor eax, eax
call scanf
pop rbp
ret