`

NASM汇编HelloWorld

阅读更多

一、Linux汇编介绍
1、DOS和Linux汇编主要不同的地方
DOS汇编中,大部分工作依靠21号中断(int 21h,DOS中断子程序)来完成,并且BIOS服务中断用int 10h(BIOS中断-显示器输出中断调用)和int 16h(BIOS中断-键盘输入中断调用);在linux中,所有的函数通过linux系统调用最终被内核处理,并且通过int 80h陷入内核代替用户空间执行,这称为linux的软中断。linux的系统调用比DOS更少但更实用。
linux是一个32位保护模式编程系统,因此我们能处理真正的现代的32位汇编,32位代码运行在flat(平板)内存模型,其基本意思就是你根本不用再担心段寄存器的处理,因为你不必用段地址来重写或者修改段寄存器,它的每个地址都是32位长,并包含一个偏移量。
x86的32位汇编代码中,你可以使用32位寄存器如eax,ebx,ecx,edx等,来代替16寄存器ax,bx,cx,dx等等。
DOS的16编程时代已经过时了,只有一些不舍得扔下386编程的一些老的黑客仍在用它,linux汇编更实用。(linux操作系统一部分由汇编代码编写,并且硬件驱动也常常离不开汇编代码,因为他是最靠近硬件的语言)

2、一个汇编程序的组成
一个简单的汇编代码通常分成下面三个段:
旁注:在编译器编译并链接生成可执行文件的过程中,会出现两个section的概念——
1)一个是在生成目标文件,通常是我们所说的.o文件,目标文件也是由多个section组成,我们通常叫这个section为“节”,这里的每个section的地址是静态偏移地址,是基于0的偏移地址,而在我们链接多个目标文件(.o)及库(静态库和动态库,关于这两者,详细请看ld手册)时,实际上是经过ld链接脚本的处理并进行重定位之后,
2)把每个目标文件中的各个section放到可执行文件的一个section中,这个section我们通常叫它段(例如.text节重定位之后生成.text段,.data节重定位生成.data段等等),详细请参考ld manual

.data section(节)
这个section主要存放初始化的数据,.data section包含利用像文件名、缓冲大小,并且还可以用EQU定义常量(constant),可以使用的一些指令如:DB,DW,DD,DQ,DT
例:
section .data
         message:                   db ‘Hello world!’      ;相当于char/unsigned char* Hello world!
         msglength:       equ 12          ; 字符串长度12字节
         buffersize:        dw 1024                     ;缓冲区大小1024个字长(相当于short类型)    

.bss section              ;未初始化section
;这个section存放未初始化数据,可以用RESB,RESW,RESD,RESQ和REST指令来为你的变量申请为初始化空间。
section .bss
         filename: resb 255                                        ;255字节
         number: resb 1
         bignum: resw 1
         realarray: resq 10

.text section      ;代码section
这个section用于存放用户代码,.text section必须从global _start开始,来告诉内核程序从什么地方开始执行(类似于C或JAVA中的main函数,这里指一个开始位置)
section .text
         global _start
_start:
         pop ebx                       ;这里是程序实际开始的地方
                   .
                   .
                   .
正如你所看到的,到目前为止,或者多或少都有一点DOS的味道,下面我们通过讲解linux系统调用之后,便可以完成你的第一个linux汇编程序了。

3、linux系统调用
linux系统调用和DOS系统调用并不完全一样:
1. 放系统调用号到eax中
2. 设置系统调用参数到ebx,ecx等
3. 调用相关中断(DOS:21h; linux:80h)
4. 返回结果通常保存在eax中
对于系统调用,x86有6个寄存器可以使用,分别是是ebx,ecx,edx,esi,edi,ebp,如果参数多于6个,ebx必须包含一个参数存放的地址,但我们通常不必担心,因为系统调用不大可能超过6个参数,更为激动的是,linux系统调用设计一贯都遵守这个原则。
下面是一些可能有帮助的例子:
move ax,1                           ;sys_exit系统调用号
mov ebx,0                           ;exit参数0,相当于exit(0)
int 80h                                  ;80中断,通常中软中断,调用它意思就是告诉内核,你处理它
接下来,你需要知道的是如何知道系统调用是什么,它们什么功能,有几个参数等等?首先,所有的系统调用和对应的系统调用号都可以在/usr/include/asm/unistd.h中找到,在调用int 80h之前,你需要将它们存入eax中。看一看系统调用表,可以看到比如sys_write(4)、sys_nice(34)和sys_exit(1),4、34、1表示对应的系统调用的系统调用号。

4、最简单的程序HELLO WORLD
; hello.asm
section .data            ; 数据段声明
        msg db "Hello, world!", 0xA     ; 要输出的字符串
        len equ $ - msg                 ; 字串长度

section .text            ; 代码段声明
global _start            ; 指定入口函数
_start:                  ; 在屏幕上显示一个字符串
;1、设置系统调用号4,采用软中断80可以陷入内核执行
;所有的系统调用和对应的系统调用号都可以在/usr/include/asm/unistd.h中找到
;4号系统调用号为write这个系统调用
mov eax, 4       ; 系统调用号(sys_write)

;2、设置系统调用参数
;man 2 write 可以查看write系统调用的功能
;write函数原型: ssize_t write(int fd,const void *buf,size_t count);
        mov ebx, 1       ; 参数一:文件描述符(stdout)
        mov ecx, msg     ; 参数二:要显示的字符串
        mov edx, len     ; 参数三:字符串长度
        int 0x80         ; 调用内核功能。软中断,陷入内核

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        ; 退出程序
;3、设置系统调用号1,采用软中断80可以陷入内核执行
mov eax, 1       ; 系统调用号(sys_exit)
;4、设置系统调用参数
        mov ebx, 0       ; 参数一:退出代码
        int 0x80         ; 调用内核功能

编译和运行方法:
[hadoop@sam1 test_sam]$ ls
hello.asm
[hadoop@sam1 test_sam]$ nasm -f elf hello.asm
[hadoop@sam1 test_sam]$ ls
hello.asm  hello.o
[hadoop@sam1 test_sam]$ ld -s -o hello hello.o
[hadoop@sam1 test_sam]$ ls
hello  hello.asm  hello.o
[hadoop@sam1 test_sam]$ ./hello
Hello, world!
[hadoop@sam1 test_sam]$

命令说明:
nasm -f elf hello.asm-->汇编
****************************************************************************************************************************************************************
-f [format] Specifies the output file format. To see a list of valid  output formats, use the -hf option.
nasm -hf可以查看到:
valid output formats for -f are (`*' denotes default):
  * bin       flat-form binary files (e.g. DOS .COM, .SYS)
    ith       Intel hex
    srec      Motorola S-records
    aout      Linux a.out object files
    aoutb     NetBSD/FreeBSD a.out object files
    coff      COFF (i386) object files (e.g. DJGPP for DOS)
    elf32     ELF32 (i386) object files (e.g. Linux)
    elf64     ELF64 (x86_64) object files (e.g. Linux)
    as86      Linux as86 (bin86 version 0.3) object files
    obj       MS-DOS 16-bit/32-bit OMF object files
    win32     Microsoft Win32 (i386) object files
    win64     Microsoft Win64 (x86-64) object files
    rdf       Relocatable Dynamic Object File Format v2.0
    ieee      IEEE-695 (LADsoft variant) object file format
    macho32   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
    macho64   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
    dbg       Trace of all info passed to output stage
    elf       ELF (short name for ELF32)
    macho     MACHO (short name for MACHO32)
    win       WIN (short name for WIN32)
****************************************************************************************************************************************************************

ld -s -o hello hello.o-->链接;貌似不写-s这个选项也能成功!
****************************************************************************************************************************************************************
ld命令
ld combines a number of object and archive files, relocates their data and ties up symbol references. Usually the last step in compiling a program is to run ld.
参数
-o Use output as the name for the program produced by ld; if this option is not specified, the name a.out is used by default.
-s Omit all symbol information from the output file.
****************************************************************************************************************************************************************

参考资料:
NASM x86汇编入门指南
http://blog.csdn.net/flickedball/archive/2009/11/15/4812051.aspx

NASM helloworld实例
http://hi.baidu.com/wolfand11/blog/item/08a153ee0df56d202cf5348e.html
分享到:
评论

相关推荐

    NASM 汇编编译器(可写跨平台任务和操作系统!)

    1.我在程序包里还加入了一个简单的操作系统源码,只能显示个“Hello, OS World”,源码文件名是“boot.asm” 2.编译方法:打开nasmpath.bat文件,键入 NASM 源码文件名 -o 输出文件名 NASM是编译器名,-O是输出...

    nasm 汇编语言 nasm 汇编语言

    **NASM汇编语言详解** NASM(Netwide Assembler)是一种流行的、开源的、支持Intel x86架构的汇编语言编译器。它以其简单易读的语法和广泛的平台支持而受到开发者喜爱。在本文中,我们将深入探讨NASM汇编语言的基本...

    Nasm 汇编 编译器

    **NASM汇编编译器详解** NASM(Netwide Assembler)是一款高效、功能强大的汇编语言编译器,支持多种操作系统,包括Linux和Windows。它的语法简洁明了,即使是初学者也能快速上手,这也是它受到广泛赞誉的原因之一...

    跨平台的汇编编译器nasm中文手册

    **NASM汇编编译器中文手册** NASM(Netwide Assembler)是一款流行的、开源的、跨平台的汇编语言编译器,它支持多种架构,包括x86、x64、ARM等。这款编译器因其简单易用、高效且功能强大的特点,在编程领域特别是低...

    nasm 开源汇编编译器

    以上代码展示了如何使用NASM编写一个简单的"Hello, World!"程序,通过Linux系统调用输出文本到标准输出。 总之,NASM作为一款强大的开源汇编编译器,具有广泛的适用性和高度的灵活性,无论是初学者还是资深开发者,...

    nasm代码-Hello, world!

    下面我们将详细探讨NASM汇编器和“Hello, world!”程序的实现。 NASM全称为Netwide Assembler,是一款开源、免费的x86架构汇编器,支持多种输出格式,如Linux下的ELF、Windows下的PE等。它拥有简洁的语法,易于学习...

    nasm汇编器,很好用的

    对于初学者,可以从简单的“Hello, World!”程序开始,逐步深入到更复杂的示例。 在使用NASM-2.08rc4时,需要注意这是一个测试版本,可能会存在一些已知或未知的问题。在正式项目中,通常推荐使用稳定版本以确保...

    NASM.rar_linux 汇编_nasm_nasm lin

    "NASM中文手册.pdf"是一个重要的参考资料,它详细介绍了NASM汇编器的使用方法和语法规则。手册通常会包含以下内容: 1. NASM安装:在Linux环境下,通常通过包管理器如`apt-get`或`yum`来安装NASM。 2. NASM语法:...

    asm.zip_asm hello world_world

    标题 "asm.zip_asm hello world_world" 和描述 "asm hello world test" 暗示了这个压缩包的内容与汇编语言编程有关,特别是涉及到一个简单的 "hello world" 程序的创建和测试。汇编语言是计算机编程的一种底层语言,...

    一个简单的x86架构下的汇编语言脚本示例,在控制台上输出"Hello, World!"

    在这个例子中,我们使用NASM汇编语言编写了一个简单的程序来输出“Hello, World!”。 - **编译过程**: - 首先确保已经安装了NASM汇编器。在大多数Linux发行版中,可以通过包管理器安装,例如使用`sudo apt-get ...

    nasm vs2010 汇编环境搭建

    - 编写汇编代码,例如一个简单的"Hello, World!"程序: ```assembly section .data hello db 'Hello, World!',0 section .text global _start _start: mov eax, 4 ; sys_write syscall number mov ebx, 1 ...

    VS2015使用NASM编译32位汇编文件

    在本文中,我们将深入探讨如何在Visual Studio 2015环境下使用NASM(Netwide Assembler)编译32位汇编语言程序。NASM是一款功能强大的、开源的汇编器,支持X86和X86_64架构,广泛应用于Windows、Linux和Mac OS等操作...

    hello nasm masm linux

    标题中的“hello nasm masm linux”表明我们将探讨与NASM、MASM汇编语言以及Linux操作系统相关的知识。这三个元素都是计算机科学和技术领域的重要组成部分,尤其是对于底层编程和系统级开发来说。 首先,我们来了解...

    nasm-2.12.02-win64.zip

    **NASM汇编器详解** NASM(Netwide Assembler)是一个开源、高效的汇编语言编译器,专为X86架构设计,支持多种操作系统,包括Windows、Linux、FreeBSD等。NASM的全称源于其最初的开发目标——成为网络广泛适用的...

    nasm-2.13.03.tar.gz安装包

    **NASM汇编编译器介绍** NASM(Netwide Assembler)是一款开源、免费的x86架构汇编语言编译器,广泛应用于Linux、Windows以及其他多种操作系统。它支持Intel和AT&T两种语法风格,并且具有高度可移植性和易用性。...

    nasm.exe和中文文档

    通过编写简单的程序,如打印“Hello, World!”,逐步过渡到更复杂的任务,如内存管理、进程调度等,将有助于巩固理论知识并提升实际操作技能。 **总结** 掌握NASM汇编器对于深入学习计算机底层机制,尤其是进行...

    nasm 语言

    编写完NASM源代码后,需要使用NASM汇编器将其转换为二进制目标文件。这可以通过命令行工具`nasm`完成,如`nasm -f elf32 hello.asm`。生成的目标文件通常是`.o`格式,然后需要使用链接器(如`ld`或`gcc`)将目标文件...

Global site tag (gtag.js) - Google Analytics