demo

有时候写好汇编代码以后,想给数据段 .data 或者代码段 .text 指定地址,可以考虑写一个简单的链接脚本来做这样的事 。
代码如下:

root@iZ2zee0spkwcgvz4do5kt2Z:~/docker_use/free_study/ld_study/ld_asm# cat hello2.S
.text
.global _start
_start:
        movl $len,%edx
        movl $msg,%ecx
        movl $1,%ebx
        movl $4,%eax
        int $0x80

        movl $0,%ebx
        movl $1,%eax
        int $0x80
.data
msg:
        .ascii "hello,world\n"
        len=.-msg
        .ascii "after hello\n"
        len2=.-msg

先 as 一下,生成对象文件 hello2.o

as -o hello2.o hello2.S

正常情况下,接下来直接链接一下就可以生成可执行文件 ld -o hello2.elf hello2.o , 但是这样话程序的数据段和代码段这些地址都是由编译器给定的 ,可能不是我们想要的地址,如果要给各个段指定地址话,可以用如下链接脚本:

root@iZ2zee0spkwcgvz4do5kt2Z:~/docker_use/free_study/ld_study/ld_asm# cat linker2.script
/*
 * Linker script for the factorial
 */
OUTPUT(hello2.elf)
OUTPUT_FORMAT("elf64-x86-64")
INPUT(hello2.o)

SECTIONS
{
        . = 0x400000;
        .text : {
              hello2.o(.text)
        }

        . = 0x600000;
        .data : {
              *(.data)
        }
}

链接脚本功能很简单,输入输出都写的很清楚,所以链接一下:

root@iZ2zee0spkwcgvz4do5kt2Z:~/docker_use/free_study/ld_study/ld_asm# ld -T linker2.script

检查一下 ,能够看到数据段和代码段的地址变成我们指定的地址了,如下:

root@iZ2zee0spkwcgvz4do5kt2Z:~/docker_use/free_study/ld_study/ld_asm# readelf -s ./hello2.elf

Symbol table '.symtab' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400000     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000600000     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello2.o
     4: 000000000000000c     0 NOTYPE  LOCAL  DEFAULT  ABS len
     5: 0000000000600000     0 NOTYPE  LOCAL  DEFAULT    2 msg
     6: 0000000000000018     0 NOTYPE  LOCAL  DEFAULT  ABS len2
     7: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS
     8: 0000000000400000     0 NOTYPE  GLOBAL DEFAULT    1 _start

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐