博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
5、Linux汇编——动态链接库
阅读量:6041 次
发布时间:2019-06-20

本文共 2885 字,大约阅读时间需要 9 分钟。

hot3.png

1、使用动态链接库

 (1)不调用库函数

 下面的程序不使用动态库,直接将hello world 输出到屏幕上并退出。源代码存放在文件helloworld-nolib.s中。

.include "linux.s".section .data    helloworld:    .ascii "hello world\n"    helloworld_end:    .equ helloworld_len, helloworld_end - helloworld .section .text.globl _start    _start:    movl $STDOUT, %ebx               movl $SYS_WRITE, %eax               movl $helloworld, %ecx               movl $helloworld_len, %edx               int $LINUX_SYSCALL                              movl $0, %ebx               movl $1, %eax               int $LINUX_SYSCALL

编译、链接、执行该函数

as helloworld-nolib.s -o helloworld-nolib.o

ld hellowordl-nolib.o -o helloworld-nolib

(2)调用库函数

下面程序将调用C库中的printf函数和exit函数。功能还是打印hello world,并退出程序。源代码保存在helloworld-lib.s文件中。

.section .data    helloworld:    .ascii "hello world\n".section .text    .globl _start    _start:    pushl $helloworld               call printf                              pushl $0               call exit

编译、链接、执行上面程序:

as helloworld-lib.s -o helloworld-lib.o

ld -dynamic-linker /lib/ld-linux.so.2 -o helloworld-lib helloworld-lib.c -lc

说明:(1)ld-linux.so.2文件是动态库载入有关的文件,其主要作用是指导目标文件如何载入动态库。其为glibc的库文件。

(2)-lc表示连接到c库,该库在系统上的文件名为libc.so,动态库的一般格式为:lib + 库名 + .so

(3)程序执行步骤:a、加载文件/lib/ld-linux.so.2,这个为动态链接器,其会查看helloworld程序,并连接C库

                                链接器会在标准目录:/etc/ld.so.conf和环境变量LD_LIBRARY_PATH中的目录下查找名为libc.so的库。

                                b、在库中查找printf和exit函数

                                c、调用被调函数

(4)下面命令查看执行文件所依赖的库文件:ldd  ./helloworld-nolib

                                                                     ldd ./helloworld-lib

(3)调用printf函数

printf函数将返回的打印出来的整数返回到%eax中。存入文件printf-example.s中

#目的:演示调用printf函数.section .data    #该字符串为格式字符串,printf用该参数确定后续的参数个数    firststring:    .ascii "Hello! %s is a %s who loves the number %d\0"    name:            .ascii "Zhang\0"    personstring:    .ascii "person\0"    numberloved:    .long 3.section .text    .globl _start    _start:        #注意传递参数顺序与函数原型中列出的顺序相反                   pushl numberloved   #%d                   pushl $personstring                   pushl $name                   pushl $firststring                   call printf                                      pushl $0                   call exit

编译、链接、运行

as printf-example.s -o printf-example.o

ld printf-example.o -o printf-example -lc -dynamic-linker /lib/ld-linux.so.2

./printf-example

说明:(1)注意到参数的入栈顺序要逆序入栈

(2)即使所传递的参数不足一个字,也按一个字存储

(3)多数库在/usr/lib或/lib下,如果查看库中定义了哪些函数,用命令:objdump -R 库的完整路径

2、创建动态库

将上篇的write-record.s和read-record.s创建成动态库,其指令如下:

as write-record.s -o write-record.o

as read-record.s -o read-record.o

链接:ld -shared write-record.o read-record.o -o librecord.so

使用新建的库:as write-records.s -o write-records.o

ld -L . -dynamic-linker /lib/ld-linux.so.2 -o write-records -lrecord write-records.o

说明:(1)-L 告诉链接器在当前目录下搜索库(通常只搜索/lib 和 /usr/lib等库)

    (2)选项 -lrecord告诉链接器在librecord.so文件中搜索相应函数。

(3)动态连接器默认情况下只在/lib、/usr/lib 和/etc/ld.so.conf中搜索库,如果运行此程序,需添加当前地址运行库:

LD_LIBRARY_PATHS=.

export LD_LIBRARY_PATH

此时,直接输入./write-records即可执行程序。

转载于:https://my.oschina.net/u/438386/blog/547546

你可能感兴趣的文章
工作第十三周:身体掏空,精神饱满
查看>>
Linux 内核--任务0的运行(切换到用户模式)move_to_user_mode
查看>>
ios扩展机制objc_setAssociatedObject,objc_getAssociatedObject
查看>>
批量添加-fno-objc-arc
查看>>
二叉树的层序遍历
查看>>
os模块
查看>>
安装 matplotlib
查看>>
css伪类(:before和:after)
查看>>
react native TypeError network request failed
查看>>
PLSQL锁表之后改如何操作
查看>>
Sql注入、文件上传与手机品牌信息抓取解决方案
查看>>
SQLServer跨库查询--分布式查询[转载]
查看>>
django错误-NoReverseMatch at /admin/
查看>>
Laravel中的信息验证 和 语言包
查看>>
折半查找法(二分查找 java版)
查看>>
工作两周年—--个人知识体系梳理
查看>>
win2003开启telnet
查看>>
php配置文件php.ini中文详解
查看>>
关于Tomcat配置相关总结
查看>>
安装PDO_MYSQL遇到的问题:error: Cannot find MySQL header files under
查看>>