第49部分- Linux x86 64位汇编 创建静态库和动态库

第49部分- Linux x86 64位汇编 创建静态库和动态库

如果为每个汇编语言函数创建单独的目标文件,会导致文件数量剧增。

可以通过使用库来简化汇编函数的目标文件问题。

GNC的C编译器可以不在命令行中独立的包含每个单独的函数目标文件,允许把所有目标文件组合在单一存档文件中。当编译C主程序时,要做的所有工作就是包含单一的目标存档文件。

存档文件可以用于编译任何使用存档文件中包含的任何函数的程序,这种存档文件就是库文件library file.

         经常按照应用程序类型或者函数类型把函数分组在一起,单一应用程序项目中可以使用多个库文件。

         库文件中包含的目标代码被编译器编译到了主程序中,这类库文件成为静态文件。函数的目标代码被编译到可执行代码中之后,可执行程序的运行就不需要库文件了。这样每个程序都包含了函数的代码。

         在linux中使用ar命令创建静态文件。

         Ar的命令行选项如下:

可以用一个或多个修饰符修改基本选项:

创建静态库

Linux操作系统中的静态库命名为libx.a

其中x是库的名称。

我们将C调用汇编中的几个文件汇编成一个静态文件。

先生成目标文件:

as -o square.o square.s

as -o areafunc.o areafunc.s

as -o cpuidfunc.o cpuidfunc.s

生成库文件:

ar -r liblearn.a square.o areafunc.o cpuidfunc.o

通过tv参数可以查看

ar -tv liblearn.a

创建库文件后,可以创建库的索引来帮助必须和库连接的其他程序的编译速度。

ranlib liblearn.a

可以通过nm命令来查看库文件中的函数的符号

nm liblearn.a

使用静态库

然后我们重新编译之前的函数:

gcc -o inttest inttest.c square.s

现在使用静态编译库编译命令如下:

gcc -o intest inttest.c liblearn.a

两者编译出来的大小是一样的。

创建动态库

我们知道windows中的动态库是DLL文件。

在Linux里面就是.so文件。

在说明动态库之前,我们来看下为什么要用动态库。

静态文件的优缺点

  • 库文件已修改,所有依赖此函数的应用程序都要重新编译。强耦合。
  • 程序要包含使用到的每个函数代码,程序会变大。浪费空间。
  • 多个程序使用相同的函数,都需要将该函数 加载到内存,浪费内存。

共享库就是解决这些问题的,它包含函数目标代码的单独文件,被加载到操作系统的通用区域中。当应用程序需要访问共享库中的函数时,操作系统自动把函数代码加载到内存中,并且允许应用程序访问它。

创建共享库

Linux对共享库的命名约定是libx.so

X是库名称,扩展名.so是表示共享库。

根据上面的3个汇编文件我们创建一个共享库

gcc -shared -o liblearn.so square.o areafunc.o

gcc -shared -fPIC -o liblearn.so square.o areafunc.o

 

这里去掉了cpuidfunc函数,因为该汇编文件不符合动态库要求。

也可以使用nm进行查看。

nm -D liblearn.so

使用共享库

还是以之前的inttest.c文件为例,之前的编译命令为:

gcc -o inttest inttest.c square.s

动态库的编译方式如下:

gcc -o inttest -L. -llearn inttest.c
或者如下:

gcc inttest.c  liblearn.so -o inttest

我们要知道动态库不会编译到C程序中,但是编译器需要知道如何访问函数,使用-l选项加上共享库的名称(减去lib部分和.so扩展名)。使用-L选项通知编译器在哪里查找它。如果共享库位于和程序文件相同的目录中,可以使用本地的目录。

反汇编后,我们可以发现可执行文件中不包含函数代码。

 

 

另外可以使用ldd命令来查看可执行文件依赖什么共享库。

# ldd inttest

    linux-vdso.so.1 (0x00007ffcafbe0000)

    liblearn.so => /root/liblearn.so (0x00007fcb5c89b000)

    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcb5c4aa000)

    /lib64/ld-linux-x86-64.so.2 (0x00007fcb5cc9f000)

 

共享库的程序的变量

动态加载器访问动态库的方法有两种:

  • LD_LIBRARY_PATH
  • /etc/ld.so.conf文件

例如 export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:."

/etc/ld.so.conf文件保存动态加载器在哪些目录中查找库的目录清单,主要是系统动态库。

修改后需要执行ldconfig进行加载。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值