Вслед за Почему виртуальный адрес точки входа в 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.
- Что здесь происходит?
- Какие адреса памяти я могу выбрать, какие я не могу выбрать и почему?
Спасибо.