下面的程序不使用动态库,直接将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
下面程序将调用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
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 库的完整路径
将上篇的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即可执行程序。