# #assembly #segmentation-fault #x86-64
Вопрос:
Почему у меня возникает ошибка сегментации?
Я использую nasm -f elf64 t.asm -o t.o
ld t.o -o t
для компиляции в Linux.
Я сделал все, что мог придумать.
section .data:
variable_int db 1
variable_string db "yaaaa", 10
section .text:
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, variable_string
mov rdx, 14
syscall
mov rax, 60
mov rdi, 0
syscall
Комментарии:
1. Я не получаю segfault, когда пытаюсь запустить вашу программу, но ваш параметр длины для
write
системного вызова больше, чем длина строки вvariable_string
.
Ответ №1:
section .data:
section .text:
Опустите двоеточия. Директива раздела не является меткой, и двоеточие анализируется как часть имени раздела. Это приводит к тому, что ваши данные помещаются в раздел с именем .data:
, в то время как компоновщик ожидает раздел с именем .data
без двоеточия. Это может привести к тому, что разделу будут предоставлены неправильные разрешения (например .text:
, раздел, который не является исполняемым).
Также:
mov rdx, 14
Этот параметр-длина записываемых данных, а длина вашей строки не 14 байт, а всего 6. Это может привести к записи дополнительного мусора (который может содержать или не содержать видимых символов) или потенциально к сбою системного вызова, если это приведет к потере сопоставленной памяти.
Комментарии:
1. Забавный факт: в текущем Linux длина, которая переходит на несопоставленную страницу, не возвращает значение-EFAULT, если только не было 0 допустимых байтов. Он записывает байты на страницу без сопоставления и возвращает количество байтов, которое он мог бы скопировать. (Я забыл, тестировал ли я с действительно крошечными буферами, подобными этому, ближе к концу страницы; Я тестировал с размером ~4k, начиная с начала страницы.)