在 Linux 操作系统中,你有很多办法可以实现在屏幕上显示一个字符串,但最简洁的方式是使用 Linux 内核提供的系统调用。使用这种方法最大的好处是可以直接和操作系统的内核进行通讯,不需要链接诸如 libc 这样的函数库,也不需要使用 ELF 解释器,因而代码尺寸小且执行速度快。
我们分别使用nasm和gas两种汇编器来编译我们的程序,这样我们可以看到Intel和AT&T两种语法格式了。
使用的工具
当然首先我们需要汇编编译器nasm和gas。然后我们需要链接器-ld,因为汇编编译器是生成的只是object代码。
Linux是一个32位的,运行在保护模式下的操作系统,使用的是flat memory 模式,使用ELF格式的二进制代码。
一个程序可以划分为下面几个部分: .text,.data,.bss。.text是一些只读的代码,.data是可读可写的数据区,.bss则是可读可写的没有初始化的数据区。当然可以有其他一些标准的部分,也可以使用户自己定义的sections,但是我们这里不关心。一个程序至少有.text部分。
下面就是我们的第一个程序“hello,world”。我们给出两个版本,分别是nasm和gas两种。
NASM (hello.asm)
--------------
; hello.asm
section .data ; 数据段声明
msg db "Hello, world!", 0xA ; 要输出的字符串
len equ $ - msg ; 字串长度
section .text ; 代码段声明
global _start ; 指定入口函数
_start: ; 在屏幕上显示一个字符串
mov edx, len ; 参数三:字符串长度
mov ecx, msg ; 参数二:要显示的字符串
mov ebx, 1 ; 参数一:文件描述符(stdout)
mov eax, 4 ; 系统调用号(sys_write)
int 0x80 ; 调用内核功能
; 退出程序
mov ebx, 0 ; 参数一:退出代码
mov eax, 1 ; 系统调用号(sys_exit)
int 0x80 ; 调用内核功能
对于nasm,下面的语法:
$ nasm -f elf hello.asm
然后我们就要使用这个object文件来生成可执行代码。这里使用链接器链接:
$ ld -s -o hello hello.o
这样我们就获得了我们的可以执行的代码“hello,world”。
AT&T 格式
#hello.s
.data # 数据段声明
msg : .string "Hello, world!\\n" # 要输出的字符串
len = . - msg # 字串长度
.text # 代码段声明
.global _start # 指定入口函数
_start: # 在屏幕上显示一个字符串
movl $len, %edx # 参数三:字符串长度
movl $msg, %ecx # 参数二:要显示的字符串
movl $1, %ebx # 参数一:文件描述符(stdout)
movl $4, %eax # 系统调用号(sys_write)
int $0x80 # 调用内核功能
# 退出程序
movl $0,%ebx # 参数一:退出代码
movl $1,%eax # 系统调用号(sys_exit)
int $0x80 # 调用内核功能
编译命令一样:(假设汇编源文件名为:hello.s)
$ as hello.s -o hello.o
$ ld hello.o -o hello
附录:
linux2.6.28内核源码:
sys_write
376 asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_ t count)
377 {
378 struct file *file;
379 ssize_t ret = -EBADF;
380 int fput_needed;
381
382 file = fget_light(fd, &fput_needed);
383 if (file) {
384 loff_t pos = file_pos_read(file);
385 ret = vfs_write(file, buf, count, &pos);
386 file_pos_write(file, pos);
387 fput_light(file, fput_needed);
388 }
389
390 return ret;
391 }
sys_exit
1146 asmlinkage long sys_exit(int error_code)
1147 {
1148 do_exit((error_code&0xff)<<8);
1149 }
阅读(1436) | 评论(0) | 转发(0) |