Далее Почему виртуальный адрес точки входа выполнения ELF имеет форму 0x80xxxxx, а не 0x0? и Почему адреса виртуальной памяти для двоичных файлов Linux начинаются с 0x8048000? , почему я не могу заставить ld
использовать точку входа, отличную от точки входа по умолчанию, с помощью ld -e
?
Если я это сделаю, я либо получу ошибку сегментации
с кодом возврата 139, даже для адресов, близких к точке входа по умолчанию. Почему?
РЕДАКТИРОВАТЬ:
Я уточню вопрос:
.text
.globl _start
_start:
movl $0x4,%eax # eax = code for 'write' system call
movl $1,%ebx # ebx = file descriptor to standard output
movl $message,%ecx # ecx = pointer to the message
movl $13,%edx # edx = length of the message
int $0x80 # make the system call
movl $0x0,%ebx # the status returned by 'exit'
movl $0x1,%eax # eax = code for 'exit' system call
int $0x80 # make the system call
.data
.globl message
message:
.string "Hello world\n" # The message as data
Если я скомпилирую это с помощью как program.s -o program.o
, а затем свяжу его статически с помощью ld -N program.o -o program
, readelf -l program
показывает 0x0000000000400078
как VirtAddr
текстового сегмента и 0x400078
в качестве точки входа. При запуске печатается «Hello world».
Однако, когда я пытаюсь установить ссылку с помощью ld -N -e0x400082 -Ttext = 0x400082 program.o -o program
(перемещение сегмента текста и точки входа на 4 байта), программа будет убита
. Проверка с помощью readelf -l
теперь показывает два разных заголовка типа LOAD
, один по адресу 0x0000000000400082
и один по адресу 0x00000000004000b0
.
Когда я пробую 0x400086
, все работает, и есть только один раздел LOAD
.
Спасибо.