Ошибка сегментации при записи сборки x86_64 в раздел .данные:

# #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, начиная с начала страницы.)