Процедура вызова ошибки сегментации NASM-64bits - PullRequest
0 голосов
/ 13 декабря 2018

При запуске программы возникает ошибка сегментации.Программа состоит из простого сложения двух чисел, сохранения значения в переменной и последующего его распечатывания с использованием системного вызова.

Вот код, в котором я его называю:

section .bss
    res: resq 1
    fout: resq 1

section .data
     msg dq 'Hello, world!', 0xa  ;string to be printed
     len equ $ - msg     ;length of the string 
     filename dq 'hello.txt'

section .text
     global _start:     ;must be declared for linker (ld)

_start:             ;tells linker entry point
     mov rcx,5
     mov rdx,4
     call sum
     mov [res],rax

     mov    rdx,1     ;message length
     mov    rcx,res  ;message to write
     mov    rbx,1       ;file descriptor (stdout)
     mov    rax,4       ;system call number (sys_write)
     syscall        ;call kernel

     mov    rax,1       ;system call number (sys_exit)
     syscall       ;call kernel

 sum:
     mov rax,rcx
     add rax,rdx
     add rax,'0'
     ret

Отладочная информация:

 (gdb) n
 sum () at Hello.asm:41
 41              mov rax,rcx
 (gdb) n
 42              add rax,rdx
 (gdb) n
 43              add rax,'0'
(gdb) n
 sum () at Hello.asm:44
 44              ret
 (gdb) n
 0x0000000000000001 in ?? ()
 (gdb) n
 No se pueden encontrar límites en la función actual
 (gdb) quit

Результатом является ошибка сегментации.

1 Ответ

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

Вы пытаетесь сохранить 8 байтов в res с mov [res],rax, несмотря на то, что только 1 байт был выделен для res.Хотя это не так, это не проблема, которая вызывает сбой вашей программы.Напишите mov [res], al, чтобы исправить это.

Настоящая проблема в том, что номера ваших системных вызовов неверны.Для i386 Linux вы используете номера системных вызовов, но это системные вызовы amd64, которые имеют разные номера.Обратитесь к значениям в asm/unistd_64.h для правильных номеров системных вызовов.Для вашего примера правильные числа: 1 для sys_write и 60 для sys_exit.Исправление этих чисел делает вашу программу более не аварийной, но она по-прежнему не работает правильно.

Вам также необходимо исправить используемые регистры.Соглашение о вызовах для системных вызовов на amd64 отличается от i386;вы не помещаете аргументы в ebx, ecx и т. д. Вместо этого вы используете rdi, rsi, rdx, r10, r8 и r9, как указано в этого ответа.Исправление делает вашу программу, наконец, работать.

...