1 Linux系统调用方法

使用Linux系统调用 write()接口, 向操作系统发送中断请求

编写一个汇编文件 hello.s

hello.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[chunli@192 lab]$ cat hello.s
#汇编语言 Hello world

.section
.data
output:
.asciz "hello world\n"

.section
.text

.global
_start
_start:
movl $4, %eax #EAX 系统调用号: 4 向终端打印数据
movl $1, %ebx #EBX 要写入的文件描述符
movl $output, %ecx #ECX 数据地址
movl $13, %edx #EDX 数据长度
int $0x80 #发起系统调用中断

movl $1, %eax #EAX 系统调用号: 1 退出程序
movl $0, %ebx #EBX 退出程序的 返回值号
int $0x80 #发起系统调用中断
[chunli@192 lab]$

汇编,链接,运行

1
2
3
4
5
[chunli@192 lab]$ as -o hello.o hello.s
[chunli@192 lab]$ ld -o hello hello.o
[chunli@192 lab]$ ./hello
hello world
[chunli@192 lab]$

直接使用gcc

将 _start 符号改为 main, 就可以使用 gcc 来编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[chunli@192 lab]$ cat hello.s
#汇编语言 Hello world

.section
.data
output:
.asciz "hello world\n"

.section
.text

.global
main
main:
movl $4, %eax #EAX 系统调用号: 4 向终端打印数据
movl $1, %ebx #EBX 要写入的文件描述符
movl $output, %ecx #ECX 数据地址
movl $13, %edx #EDX 数据长度
int $0x80 #发起中断

movl $1, %eax #EAX 系统调用号: 1 退出程序
movl $0, %ebx #EBX 退出程序的 返回值号
int $0x80 #发起中断
[chunli@192 lab]$
[chunli@192 lab]$ gcc hello.s && ./a.out
hello world
[chunli@192 lab]$

2 调用C语言库函数 方法

调用libc 库中的 printf()函数, 向终端打印字符串

使用 libc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[root@192 ~]# cat hello.s
#汇编语言 Hello world
#适用于32位Linux, Intel CPU
#64位 Linux 不可用

.section
.data
output:
.asciz "hello world\n"

.section
.text

.global
_start
_start:
pushl $output #字符地址 入栈
call printf #函数调用
addl $4, %esp #清理栈

pushl $0 #数据 0 入栈
call exit #函数调用
[root@192 ~]#

[root@192 ~]# as hello.s -o hello.o
[root@192 ~]# ld hello.o -lc -o hello
[root@192 ~]# ./hello
-bash: ./hello: /usr/lib/libc.so.1: bad ELF interpreter: No such file or directory
[root@192 ~]#

libc 这是一个动态库,
这个提示说找不到 libc
必须指定运行时加载动态库的程序,使用ld-linux.so.2动态加载器查找libc

[root@192 ~]# as hello.s -o hello.o
[root@192 ~]# ld -dynamic-linker /lib/ld-linux.so.2 hello.o -lc -o hello
[root@192 ~]#
[root@192 ~]# file ./hello
./hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
[root@192 ~]#
[root@192 ~]# ldd ./hello
linux-gate.so.1 => (0x00229000)
libc.so.6 => /lib/libc.so.6 (0x00bc6000)
/lib/ld-linux.so.2 (0x800a0000)
[root@192 ~]#
[root@192 ~]# ./hello
hello world
[root@192 ~]#