免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1094 | 回复: 0
打印 上一主题 下一主题

linux 汇编学习之hello world(intel和at&t) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-10-28 20:03 |只看该作者 |倒序浏览

                在 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)
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/104384/showart_2081406.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP