汇编语言编写的Hello World

Linux 下用汇编语言编写的代码具备两种不一样的形式。第一种是彻底的汇编代码,指的是整个程序所有用汇编语言编写。尽管是彻底的汇编代码,Linux 平台下的汇编工具也吸取了 C 语言的长处,使得程序员可使用 #include、#ifdef 等预处理指令,并可以经过宏定义来简化代码。第二种是内嵌的汇编代码,指的是能够嵌入到C语言程序中的汇编代码片断。虽然 ANSI 的 C 语言标准中没有关于内嵌汇编代码的相应规定,但各类实际使用的 C 编译器都作了这方面的扩充,这其中固然就包括 Linux 平台下的 GCC。程序员

一 Linux汇编语法格式web

绝大多数 Linux 程序员之前只接触过DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的。但在 Unix 和 Linux 系统中,更多采用的仍是 AT&T 格式,二者在语法格式上有着很大的不一样.编程

二 Hello World的编写ubuntu

在 Linux 操做系统中,你有不少办法能够实如今屏幕上显示一个字符串,但最简洁的方式是使用 Linux 内核提供的系统调用。使用这种方法最大的好处是能够直接和操做系统的内核进行通信,不须要连接诸如 libc 这样的函数库,也不须要使用 ELF 解释器,于是代码尺寸小且执行速度快。
Linux 是一个运行在保护模式下的 32 位操做系统,采用 flat memory 模式,目前最经常使用到的是 ELF 格式的二进制代码。一个 ELF 格式的可执行程序一般划分为以下几个部分:.text、.data 和 .bss,其中 .text 是只读的代码区,.data 是可读可写的数据区,而 .bss 则是可读可写且没有初始化的数据区。代码区和数据区在 ELF 中统称为 section,根据实际须要你可使用其它标准的 section,也能够添加自定义 section,但一个 ELF 可执行程序至少应该有一个 .text 部分。 下面给出咱们的第一个汇编程序,用的是 AT&T 汇编语言格式:svg

例: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       # 调用内核功能

例:Intel格式工具

; 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         ; 调用内核功能

上面两个汇编程序采用的语法虽然彻底不一样,但功能却都是调用 Linux 内核提供的 sys_write 来显示一个字符串,而后再调用 sys_exit 退出程序。在 Linux 内核源文件 include/asm-i386/unistd.h 中,能够找到全部系统调用的定义。网站

三 Linux 汇编工具ui

1.汇编器
汇编器(assembler)的做用是将用汇编语言编写的源程序转换成二进制形式的目标代码。Linux 平台的标准汇编器是 GAS,它是 GCC 所依赖的后台汇编工具,一般包含在 binutils 软件包中。GAS 使用标准的 AT&T 汇编语法,能够用来汇编用 AT&T 格式编写的程序:spa

panlu@ThinkPad:~/汇编语言$ as -o hello.o helloWorld.s

Linux 平台上另外一个常常用到的汇编器是 NASM,它提供了很好的宏指令功能,并可以支持至关多的目标代码格式,包括 bin、a.out、coff、elf、rdf 等。NASM 采用的是人工编写的语法分析器,于是执行速度要比 GAS 快不少,更重要的是它使用的是 Intel 汇编语法,能够用来编译用 Intel 语法格式编写的汇编程序:

panlu@ThinkPad:~/汇编语言$ nasm -f elf hello.asm

2.连接器
由汇编器产生的目标代码是不能直接在计算机上运行的,它必须通过连接器的处理才能生成可执行代码。连接器一般用来将多个目标代码链接成一个可执行代码,这样能够先将整个程序分红几个模块来单独开发,而后才将它们组合(连接)成一个应用程序。 Linux 使用 ld 做为标准的连接程序,它一样也包含在 binutils 软件包中。汇编程序在成功经过 GAS 或 NASM 的编译并生成目标代码后,就可使用 ld 将其连接成可执行程序了:

panlu@ThinkPad:~/汇编语言$ ld -s -o hello hello.o

3 运行

panlu@ThinkPad:~/汇编语言$ ./hello
Hello World!

四 Intel格式

一、在ubuntu上安装nasm方法

首先在网站http://www.nasm.us/pub/nasm/releasebuilds/2.10.07/下面去下载2.10.07.tar.gz这个版本(通常在ubuntu上面都是使用这个压缩形式的)。若是要下其余版本的nasm能够经过http://www.nasm.us/来进行选择进行下载。

二、安装方法:使用以下的命令:

解压:tar zxvf nasm-2.10.07.tar.gz

进入刚解压的目录 cd 解压后的目录

而后执行命令:./configure
make
sudo make install

经过以上的步骤nasm就在ubuntu上安装好了。也能够经过使用命令:nasm -version来查看是否安装成功。若是出现了nasm的版本信息则说明安装成功,不然还需进一步安装。

panlu@ThinkPad:~/汇编语言$ nasm -version
NASM version 2.10.07 compiled on Sep 29 2015

3 编译运行

nasm -f elf64(elf32) hello.asm (注意这里使用elf64仍是elf32要看操做系统的位数来决定)
gcc -o hello hello.o
./hello

输出Hello World便成功了.