Вслед за Почему виртуальный адрес точки входа в ELF формы 0x80xxxxx, а не ноль 0x0? и Почему адреса виртуальной памяти для бинарных файлов Linux начинаются с 0x8048000?, почему я не могу использовать ld
другую точку входа, чем значение по умолчанию с ld -e
?
Если я это сделаю, я либо получаю segmentation fault
с кодом возврата 139, даже для адресов, закрытых точкой входа по умолчанию. Почему?
EDIT:
Я сделаю вопрос более конкретным:
.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
Если я скомпилирую это с помощью as 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 байта), программа будет killed
. Осмотр с помощью readelf -l
теперь показывает два разных заголовка типа LOAD
, один на 0x0000000000400082
и один на 0x00000000004000b0
.
Когда я пытаюсь 0x400086
, все работает, и есть только один раздел LOAD
.
- Что здесь происходит?
- Какие адреса памяти я могу выбрать, какие я не могу выбрать и почему?
Спасибо.