汇编语言使用C库函数和Linux动态链接

本文介绍了如何在汇编语言中使用C库函数printf,详细阐述了动态链接过程,包括ld-linux.so的查找共享库顺序,以及readelf和ldd等工具在分析动态链接中的应用。
摘要由CSDN通过智能技术生成

使用printf


代码

#cpuid2.s -- Using C labrary calls  
.section .data  
output:          
		.asciz "The processor Vender is '%s'\n"
.section .bss          
		.lcomm buffer, 12  
.section .text  
.globl _start  
_start:          
		movl $0, %eax          
		cpuid          
		movl $buffer, %edi          
		movl %ebx, (%edi)   //含义同cpuid.s,向%edi所指向的buffer内存          
		movl %edx, 4(%edi)  //位置写入3个寄存器的内容,这3个寄存器存储了          
		movl %ecx, 8(%edi)  //CPU厂商信息的字符串(12字节)          
		pushl $buffer       //将buffer和output入栈,为printf提供参数          
		pushl $output          
		call printf         //调用C的printf函数          
		addl $8, %esp       //将堆栈指针回滚8个字节,达到清除printf参数的目的          
		pushl $0          
		call exit


 

.asciz是在定义字符串的时侯在字符串结尾加上空字符(即C语言的\0),这样做的目的是为了让printf能读懂字符串。

.lcomm是在本地内存区域中声明固定长度的未初始化数据,这里初始化了12个字节的空间。

程序里buffer和output内存位置的内容是要向printf传递的参数值:

一个是"The processor Vender is '%s'\n"字符串;

另外一个是由cpuid返回结果(在ebx,edx,ecx三个寄存器中)填充的buffer。


需要通过堆栈来传递参数,所以在程序中使用

pushl $buffer

pushl $output

将参数入栈,printf获取参数是自右向左,即先buffer后output,所以要把buffer后入栈。

参数入栈之后,用call指令调用printf。

exit的情况同上,使用了一个参数--常数0。


汇编

#as -o cpuid2.o cpuid2.s

采用了动态连接的方式,所以C函数没有包含在可执行程序中,需要由另外的程序在运行时加载,ld不知道这个程序在哪里,所以我们还得手动指定

动态链接

#ld -dynamic-linker /lib/ld-linux.so.2 -lc -o cpuid2 cpuid2.o

#./cpuid2

输出

The processor Vendor ID is 'GenuineIntel'

GDB调试

# gdb cpuid2  
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/zhms/AS/chap04/cpuid2...done.
(gdb) break _start
Breakpoint 1 at 0x80481b8: file cpuid2.s, line 10.
(gdb) r
Starting program: /usr/zhms/AS/chap04/cpuid2 

Breakpoint 1, _start () at cpuid2.s:10
10          movl $0, %eax
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6_3.6.i686
(gdb) i r
eax            0x0      0
ecx            0x0      0
edx            0x758470 7701616
ebx            0x767fc4 7765956
esp            0xbffff6c0       0xbffff6c0
ebp            0x0      0x0
esi            0xbffff6cc       -1073744180
edi            0x80481b8        134513080
eip            0x80481b8        0x80481b8 <_start>
eflags         0x286    [ PF SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb) s
11          cpu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值