Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2949479
  • 博文数量: 754
  • 博客积分: 10132
  • 博客等级: 上将
  • 技术积分: 7780
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-14 23:36
文章分类

全部博文(754)

文章存档

2012年(3)

2011年(39)

2010年(66)

2009年(167)

2008年(479)

我的朋友

分类: LINUX

2008-08-26 23:56:03

先看看下面通过系统调用实现的hello world代码:

.section .data
msg:
.ascii "Hello world!\n"

.section .text

.globl _start

_start:
movl $4, %eax
movl $1, %ebx
movl $msg, %ecx
movl $13, %edx
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80

系统调用是通过int 0x80来实现的,eax寄存器中为调用的功能号,ebx、ecx、edx、esi等等寄存器则依次为参数,从 /usr/include/asm/unistd.h中可以看到exit的功能号_NR_exit为1,write(_NR_write)功能号为4,因此第一个int $0x80调用之前eax寄存器值为4,ebx为文件描述符,stdout的文件描述符为1,ecx则为buffer的内存地址,edx为buffer长度。第二个int $0x80之前eax为1表示调用exit,ebx为0表示返回0。编译链接步骤如下所示:
as -o helloworld.o helloworld.s
ld -o helloworld helloworld.o

再看看调用C函数的代码:

.section .data
output:
.asciz "Hello world!\n"

.section .text

.globl _start

_start:
pushl $output
call printf
addl $8, %esp
pushl $0
call exit

这个例子相对来说看起来简单得多,将参数压入堆栈调用相应的函数即可,不过要注意的是:1、C函数需要调用的字符串参数必须以asciz声明,而不是 ascii,这样才会给字符串后面加'\0'。2、压栈顺序刚好与C函数顺序相反,最后的参数应最先入栈。3、链接的时候需要链接libc.so库并指定动态链接库加载器/lib/ld-linux.so.2,步骤如下:
as -o helloworld2.o helloworld2.s
ld -dynamic-linker /lib/ld-linux.so.2 -lc -o helloworld2 helloworld2.o

 
系统调用:
系统调用是通过int 0x80来实现的,eax寄存器中为调用的功能号,ebx、ecx、edx、esi等等寄存器则依次为参数。
/usr/include/bits/syscall.h
/usr/include/asm/unistd.h
kernelsrc/arch/um/kernel/sys_call_table.c
阅读(7374) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~