Проблемы с вызовом функции C в сборке - PullRequest
0 голосов
/ 01 декабря 2018
section .data
text db 'Put a number',10,0
scanform db '%d'
number dw 0

section .text
extern printf,scanf

global main
main:
push rbp
mov rbp,rsp
push rdi
push rsi
push rbx

mov rdi,text
mov rax,0
call printf

mov rsi,number
mov rdi,scanform
mov rax,0
call scanf

pop rbx
pop rsi
pop rdi
ret

Это мой код, я пишу другие коды весь день, и у меня нет проблем с ними, но теперь, когда я вызываю scanf, пишу программе, получаю сигнал SIGSEV, segfault ... Указывается первая и последняя строка в разных файлах,Я не понимаю это сообщение, кто-то может мне помочь?

1 Ответ

0 голосов
/ 01 декабря 2018

У вас есть следующие проблемы:

  1. Вы забыли pop rbp.
  2. Вы неправильно выровняете стек, который должен быть выровнен на 16 байт.
  3. Выне заканчивайте нулем вашу строку формата (спасибо Павлу за указание на это).
  4. Вы используете %d, который записывает 4-байтовое целое число, но вы выделили только 2 байта с dw.
  5. Рекомендуется выравнивать целые числа до 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
...