链接 集合

链接器的核心是两个:

符号表

重定位表

工具:

nm file.o

objdump -h a.out  

ld --verbose > defaults.lds 查看默认的链接脚本

gcc -fno-builtin    -fno-builtin 用于关闭GCC内部函数功能

gcc -v -nostartfiles -o hello hello.o  不链接系统标准启动文件,而标准库文件仍然正常使用

gcc -v -nostdlib -o hello hello.o  不链接系统标准启动文件和标准库文件

ld -static  链接默认是动态链接 ,静态链接需要加上static指定

程序的入口函数是由链接器文件指定或者通过gcc 指定。

ENTRY(hello)

gcc -e

链接脚本如下:

ENTRY(hello)   //入口函数不是main()了,是hello

SECTIONS
{
    .text 0x00400000+SIZEOF_HEADERS:    //指定程序的代码段从0x00400000开始(64位),32位及其为0x08048400开始
    { 

 //必须加上SIZEOF_HEADERS,否者程序将会变得很大。因为代码段占用了ELF文件的文件头,导致  ELF文件的相关信息丢失              
        *(.text)

        *(.rodata)
    }
    . = 0x01000000;//当然,不能随意指定数据的位置,否者容易引起  segment fault ,还是让程序自己处理
    s1 = .;                //指定程序中参数s1的地址在0x01000000处
    . += 4;                //不指定的话就是有系统分配的地址,可以不管
    s2 = .;               //指定程序中参数s1的地址在0x01000000+4处
    .data :
    {
        *(.data)
    } 
    .bss :
    {
        *(.bss)
    }

    /DISCARD/ :
    {
        *(*)     //放弃所有目标文件中除了前面指定的段外的所有其它段
    }
}//各个段之间存在对齐的问题

 

例子:
void printf(const char* s, int l)
{
    asm  (
        "movl $4, %%eax\n"     // _write系统函数相关
        "movl $1, %%ebx\n"
        "movq %0, %%rcx\n"  //对于64位机器,由于指针是64位的,所以这里用movq
        "movl %1, %%edx\n"
        "int $0x80     \n"    //通过80H进行interrupt
        :
        : "r"(s), "r"(l)      // printf的参数
        : "eax", "ebx", "ecx", "edx"  // 保留列表
    );
}
void exit(int code)
{
    asm  (
        "movl $1, %%eax\n"   //_exit
        "movl %0, %%ebx\n"
        "int $0x80     \n"
        :
        : "r"(code)        
        : "eax", "ebx"
    );
}

int hello()
{
    printf("D.T.Software\n", 13);
    exit(0);
}

入口程序不是main()了,而是hello()函数。

编译,汇编时和普通函数是一样处理,但是当进行连接时,需要用自己编写的链接文件,上面已经给出。

同时,由于程序中用到了printf和exit函数,这个和系统中的printf和exit冲突,如下:

所以,编译时要加上  -fno-builtin 。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值