【软件开发底层知识修炼】十一 链接器-链接脚本

上一篇文章学习了链接器之-main函数不是第一个执行的函数:main函数不是第一个执行的函数

今天继续学习链接器,学习链接是如何动作的,从而引入链接脚本的概念。本文就学习链接脚本的概念。

1、链接脚本的作用

我们都知道可重定位文件经过链接器链接后最终形成可执行文件。这个链接的过程大概就是分为符号解析和重定位。

那么链接器到底是如何工作的呢?这取决于链接脚本。我们可以看下图:

在这里插入图片描述

几个可重定位文件与相应的库文件进行链接,链接器经过链接器的指导,最终形成可执行程序。

在学习链接链接脚本的大致格式之前,先练总结一下链接脚本的几个作用(实际上这些作用我们都知道,只不过今天才知道链接脚本的存在而已):

  • 链接脚本用于描述链接器处理目标文件(可重定位文件)与库文件的方式

    1. 合并各个目标文件中的段
    2. 重定位各个段的起始地址
    3. 重定位各个符号的最终地址(这个地址实际上是段内偏移地址)

2、链接脚本的格式

链接脚本也就是一个脚本文件,语法比较简单,下面我们直接看一个例子,来说明一个链接脚本大致有哪些内容:

在这里插入图片描述

上述的的描述还是很全面很仔细的。我们主要注意一下几点:

  • 各个段的链接地址必须符合具体平台的规则,比如在Intel处理器上与在Amd处理器上,或许各个段在整个地址空间的位置就会有一些差别
  • 链接脚本中能够直接定义标识符并制定存储地址
  • 链接脚本能够直接定义源代码(需要编译的.c .c++程序)中的标识符的地址
  • 我们主要学习Linux系统,在Linux中代码段(.text段的地址范围为[0x08048000,0x08049000])

我们现在可能还不理解上面的几条注意事项,但是经过下面的例子,就一定可以理解了:

我们写了如下的C程序与链接脚本:

8-1.c

#include <stdio.h>int s1;
extern int s2;int main()
{printf("&s1 = %p\n", &s1);printf("&s2 = %p\n", &s2);return 0;
}

8-1.lds

SECTIONS
{.text 0x08048400:{*(.text)}. = 0x01000000;s1 = .;. += 4;s2 = .;.data 0x0804a800:{*(.data)}.bss :{*(.bss)}
}

我们看上面的程序,在C程序中有一个extern int s2; 这个s2不是这个C文件的,是外部文件的,很明显,我们只有两个文件,另一个就是我们指定的链接脚本文件。

使用下述命令进行编译:

  • gcc 8-1.c 8-1.lds -o lyy

生成可执行程序lyy (注意如果编译的时候不加上我们自己定义的链接脚本,编译就会出错)

运行:

  • ./lyy

执行结果为:
在这里插入图片描述

很明显,s1的地址由于我们再链接脚本中指定了:

    . = 0x01000000;s1 = .;

所以s1的地址是:0x01000000;

而由于在链接脚本中有如下的两句话:

   . += 4;s2 = .;

所以s2的地址为:0x01000004;

如果我们不使用链接脚本指定这两个变量的地址,那么他们的地址就是随机的,这也符合我们平时的结果。

3、借助链接脚本修改程序的入口函数

不知道是否还记得在上一篇文章中:点击查看。我们学习了程序的执行流程,知道了main函数并不是真正的第一个开始执行的函数。而且我们有办法在编译程序的时候改变第一个执行的程序。那个时候使用的是在编译的时候指定入口函数的地址,就像下面这样:

  • gcc -e program -nostartfiles program.c -o program

今天我们来学习另一种方法,来修改程序的入口函数。

那就是在链接脚本中指定,大概格式如下:

在这里插入图片描述

下面给出一个例子,这个例子中没有main函数,我们自己指定一个函数,然后将它设为入口函数:

8-2.c

#include <stdio.h>
#include <stdlib.h>int program()
{printf("D.T.Software\n");exit(0);
}

8-2.lds

ENTRY(program)SECTIONS
{.text 0x08048400:{*(.text)}
}

使用下面命令进行编译(也可以先编译输出目标文件,然后进行链接,下面的命令直接一步完成而已):

  • gcc -nostartfiles 8-2.c 8-2.lds -o lyy2

没有报错,生成了可执行文件lyy2

运行程序结果为:

在这里插入图片描述

很明显,我们利用这个方法成功修改了这个C程序的入口函数。

为了更加深入,我们可以看看该可执行程序的符号信息:

使用以下命令查看可执行程序lyy2

  • nm lyy2

在这里插入图片描述

由于上面的8-2.lds链接脚本指定代码段其实地址为: 0x08048400,而我们的可执行程序的入口函数(program函数)的地址其实就是代码段(.text)地址,所以如上图,T代表代码段,地址为0x08048400。很完美的解释。

4 、 默认的链接脚本

上面我们学习了链接脚本的各种知识,但是我们平时并没有使用它或者看到它。但是这并不意味着学习它就没有用处。它对于我们理解整个系统原理有很大帮助。

可以使用下面的命令查看默认的链接脚本:

  • ld --verbose > defaults.lds

上述命令将默认的链接脚本输出到文件defaults.lds文件中,我们可以打开defaults.lds文件来查看默认链接脚本文件。

5、总结

记住,我们在学习的内容是可以让你走的更远,走的更高的铺垫。或许对你产生不了直接的影响,但是绝对会对你将来的学习之路产生深远的影响。不要一口吃一个胖子,慢慢来,从应用软件做起,深入学习底层原理!你的未来一定更加美好!!!

本文参考狄泰软件学院相关课程
想学习的可以加狄泰软件学院群,
群聊号码:199546072

学习探讨加个人(可以免费帮忙下载CSDN资源):
qq:1126137994
微信:liu1126137994

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(178):表格元素

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/ html4/strict.dtd"> <html><head><meta http-equiv"content-type" content"text/html; charsetutf-8"><title>表格</ti…

java后端分享整理

java规范总结1. Java 常见的代码规范1.1. Java 自带的工具方法1.1.1 比较两个对象是否相等1.1.2 apache commons工具类库1.1.2.1 字符串判空1.1.2.3 重复拼接字符串1.1.2.4 格式化日期1.1.2.4 包装临时对象 &#xff08;不是特别常用&#xff09;1.1.3 common-beanutils 操作对…

SharePoint要在master page中动态显示List数据的几种方式

我们都知道&#xff0c;在SharePoint中&#xff0c;Content page继承自Page layout&#xff0c;而Page layout又继承自Master page。Master page的作用大家都知道&#xff0c;它定义了站点的的整体外观和公共元素&#xff0c;因此有了很强的页面重用性和很好的页面编辑体验&…

前端学习(179):表单元素

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/ html4/strict.dtd"> <html><head><meta http-equiv"content-type" content"text/html; charsetutf-8"><title>表单</ti…

【软件开发底层知识修炼】十二 C/C++语言中内嵌汇编语言(asm)

上一篇文章学习了链接脚本的语法与相关概念&#xff1a;链接脚本的概念 在继续学习链接器的内容的同时&#xff0c;先学习一个新内容&#xff1a;内嵌汇编。 GCC编译器一般支持C/C内嵌汇编语言&#xff0c;这样可以实现语言本身无法实现的内容。我们本文主要介绍C语言中的内嵌…

数据思维整理

数据思维整理分享

windows7下iis网站的.net框架版本设置

昨天下载了 VS2010 创建了一个默认的WebApplication&#xff0c;想看看在iis中运行的情况&#xff0c;虽说用了几个月的 win7 &#xff0c;但还从没有用过IIS。首先给人的感觉是IIS变化很大&#xff0c;多出了很多东西&#xff0c;让人感到很茫然。 先建个网站试试&#xff0c;…

【OS学习笔记】二十三 保护模式七:保护模式下任务的隔离与任务的特权级概念

上一篇文章学习了保护模式下操作系统内核如何加载程序并运行&#xff1a;点击链接查看上一篇文章 本篇文章接着上一篇文章学习保护模式下任务的隔离。 包括以下学习内容&#xff1a; 任务的全局空间和局部空间任务的TSS任务的LDT任务的特权级概念等 1、回顾 在保护模式下&…

[Drupal] How to add the js file and js code block in Drupal

Drupal 6:代码//This will add a JS file to your head (specifically the $scripts variable in page.tpl.php)drupal_add_js(drupal_get_path(module,my_module) ./my_module.js); //This add inline JS to the head of the documentdrupal_add_js(alert("Hello!"…

【OS学习笔记】二十四 保护模式七:调用门与依从的代码段----特权级保护

学习交流加 个人qq&#xff1a; 1126137994个人微信&#xff1a; liu1126137994学习交流资源分享qq群&#xff1a; 962535112 上一篇文章学习了保护模式下的任务与任务隔离&#xff0c;以及简单介绍了保护模式下的特权级的概念。点击链接查看上一篇文章&#xff1a;任务与任务隔…

【OS学习笔记】二十六 保护模式八:任务门---任务切换

上一篇文章学习了&#xff1a;保护模式七&#xff1a;调用门与依从的代码段----特权级保护 主要学习了以下内容&#xff1a; 描述符特权级&#xff08;目标对象的特权级&#xff09;DPL 描述符特权级&#xff08;目标对象的特权级&#xff09;DPL 当前特权级CPL 低特权级的应…

腾讯微博应用

腾讯微博开放平台提供了一些官方微博应用&#xff0c;供开发者借鉴和利用&#xff0c;其中包括&#xff1a; 一键转播——嵌入一键转播到你的网站里&#xff0c;访客便能将网页信息直接传播至腾讯微博。分享资讯的同时&#xff0c;用户通过来源链接可进入你的网站&#xff0c;从…

【OS学习笔记】二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中断嵌套

上一篇文章学习了任务门的概念&#xff1a;任务门—任务切换。主要学习了以下内容&#xff1a; 使用任务门进行任务切换的一般工作原理&#xff08;和中断有关的任务切换&#xff09; 本篇文章接着上一篇文章学习以下内容&#xff1a; 利用jmp进行任务切换利用call进行任务切…

Windows Phone 7 开发 31 日谈——第22日:应用?还是 游戏?

本文是“Windows Phone 7 开发 31 日谈”系列的第22日。 昨天&#xff0c;我发了一篇极长的关于Silverlight Toolkit for Windows Phone的文章。今天的会短一些&#xff0c;但却非常珍贵。我会讨论你的应用程序设置中非常细微但很重要的设置&#xff1a;类别&#xff08;Genre&…

《Advanced .NET Debugging》 读书笔记 Listing 3-6: 使用sxe在程序载入mscorwks之后停下来载入sos...

1. 在WinDbg下载入01MDASample.exe 2. 执行 sxe ld mscorwks.dll 该命令的作用是在进程载入mscorwks之后停下来 3. 执行 g 可见程序在载入mscorwks.dll 之后停下来了 4. 执行 .loadby sos.dll mscorwks 转载于:https://www.cnblogs.com/charrli/archive/2010/12/25/1916964.h…

转载并学习实现三重DES加密解密代码(一)

作者:finallyliuyu 出处&#xff1a;博客园 声明&#xff1a;此篇博文代码来自于邹德强先生。由于目前找到的版本是残缺版&#xff0c;所以我又进行了补全。读一份好代码&#xff0c;可以领略到作者的编程风格和语言驾驭能力&#xff0c;同时又能从其中汲取养分。现将我所修改后…

【OS学习笔记】三十 保护模式九:段页式内存管理机制概述

上几篇文章学习了任务切换相关知识&#xff0c;如下&#xff1a; 【OS学习笔记】二十六 保护模式八&#xff1a;任务门—任务切换【OS学习笔记】二十七 保护模式八&#xff1a;任务切换的方法之----jmp与call的区别以及任务的中断嵌套 今天继续学习保护模式下的分页机制。本篇…

真人拳皇项目第六次Scrum总结——史经浩

今天&#xff0c;我们组开始了正式的编码阶段&#xff0c;前期plan的时候天马行空&#xff0c;现在是脚踏实地的coding了。在Scrum上&#xff0c;大家sync了一下各自的进展&#xff0c;如下&#xff1a; 今天 进度 问题及解决 明天 田飞 work item 37528:DirectX动画的de…

【OS学习笔记】三十一 保护模式九:页目录、页表和页三者的关系详解

上一篇文章学习了&#xff1a;保护模式九&#xff1a;段页式内存管理机制概述 本篇文章接着学习以下内容&#xff1a; 页目录概念页表概念页目录、页表与页之间的关系虚拟地址&#xff08;线性地址&#xff09;到物理地址的具体变换过程。 1、页目录、页表和页的对应关系 第…

使用某个文件夹下的所有文件去替换另一个文件夹下及其子文件夹下存在的同名文件(Python实现)...

值此新年即将到来之际,在这献上今年最后一篇文章. 产生这个需求是在项目的一次图标替换上,当时给了我一堆新图标要替换原来的老图标,可是原来的老图标分布在某个文件夹下的各个子文件夹下面,而新图标全是在同一个目录下的. 手动替换的话,只能是搜索文件名后替换,但是文件很多太…