跟进为什么ELF执行入口点虚拟地址的形式是0x80xxxxxx而不是零0x0?为什么 Linux 二进制文件的虚拟内存地址从 0x8048000 开始?,为什么我不能ld
使用与默认值不同的入口点ld -e
?
如果我这样做,我会得到一个segmentation fault
返回码 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
如果我编译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
,一个 at0x0000000000400082
和一个 at 0x00000000004000b0
。
当我尝试0x400086
时,一切正常,而且只有一个LOAD
部分。
- 这里发生了什么?
- 我可以选择哪些内存地址,哪些不能选择,为什么?
谢谢。