`

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是输出...

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

    一个简单的x86架构下的汇编语言脚本示例,用于在Linux环境下使用NASM汇编器编写一个程序,该程序会在控制台上输出"Hello, World!"。 编译与运行: 首先,你需要安装NASM汇编器。在大多数Linux发行版中,你可以使用包...

    一个简单的linux汇编语言程序

    Intel语法 Intel语法是由Intel公司为其处理器编写官方文档时所采用的语法。...编译:nasm -f elf32 hello_world.asm -o hello_world.o 链接:ld -m elf_i386 hello_world.o -o hello_world 运行:./hello_world

    Bochs入门教程[操作系统第一步]

    在80x86 IBM PC 兼容计算机上用一张软盘启动引导程序,最后打印出下面的字样: ...3、汇编语言输出Hello world! 4、汇编语言动态输出当前系统时间 5、是写操作系统的第一步!! 6、可执行源码和详细教程。

    boot-sector:这是用于操作系统启动的引导扇区汇编代码!

    这是书中的源代码:“如何制作一个简单的...Eg: nasm boot_helloworld.asm -f bin -o boot_helloworld.bin 中银国际使用: QEMU 用法: qemu-system-i386 [bin_filename] Eg: qemu-system-i386 boot_helloworld.bin

    OS:简单的操作系统程序,如引导加载程序、HelloWorld 内核、操作系统计算器、设备 IO、VGA、GDT、IDT、游戏等

    内核包含用于简单 HelloWorld、键盘 I/O 等的 C 程序......以及用于低级操作的少量汇编程序。 Global_Descriptor_Table 包含在 x86 NASM 程序集和 C 中设置 GDT 的代码。 Interrupt_Descriptor_Table 包含使用...

    hello.ll:以LLVM语言为OS X实现Hello World程序的几种方法

    在这里,我演示了几种以LLVM语言为OS X实现Hello World程序的方法。 与C标准库链接至少获得write()和exit()函数。 这是最简单的方法,但是添加了不必要的libc依赖关系。 这很无聊=) 实现您自己的最小标准库(例如...

    黑客反汇编揭秘(第二版).part2.rar

    13.5 x86-64平台上的“Hello, World”程序 262 13.6 总结 267 第14章 反汇编与破解Linux内核 268 14.1 反汇编Linux内核 268 14.1.1 内核的外围话题 268 14.1.2 攻击内核 269 14.1.3 深入内核 271 14.1.4 错误...

    黑客反汇编揭秘(第二版).part1.rar

    13.5 x86-64平台上的“Hello, World”程序 262 13.6 总结 267 第14章 反汇编与破解Linux内核 268 14.1 反汇编Linux内核 268 14.1.1 内核的外围话题 268 14.1.2 攻击内核 269 14.1.3 深入内核 271 14.1.4 错误...

    Harrys-ASM-OS:几乎无法运行的操作系统

    这基本上是操作系统的“ Hello World”,并且可能不会继续前进。 ##有什么意义? 目的是在x86汇编中构建功能性的“操作系统”。 理想情况下,它将包括许多基本命令(date,ls,cat),并且能够与文件系统进行交互...

    ukernel:我第一次尝试编写内核

    你需要: gcc编译C文件gnu make使构建过程自动化nasm的汇编程序qemu运行内核[可选]用它! make run支持! 打开一个问题,我会调查一下!贡献它! 分叉项目,创建一个新分支,进行更改,然后提交合并请求。

    自己动手写操作系统 pdf

    5.1 用NASM在Linux下写Hello World146 5.2 再进一步,汇编和C同步使用148 5.3 ELF(Executable and Linkable Format)150 5.4 从Loader到内核155 5.4.1 用Loader加载ELF155 5.4.2 跳入保护模式161 5.4.3 重新放置...

    自己动手写操作系统

    5.1 用NASM在Linux下写Hello World146 5.2 再进一步,汇编和C同步使用148 5.3 ELF(Executable and Linkable Format)150 5.4 从Loader到内核155 5.4.1 用Loader加载ELF155 5.4.2 跳入保护模式161 5.4.3 重新...

    自己动手写操作系统 电子工业出版社 pdf

    5.1 用NASM在Linux下写Hello World146 5.2 再进一步,汇编和C同步使用148 5.3 ELF(Executable and Linkable Format)150 5.4 从Loader到内核155 5.4.1 用Loader加载ELF155 5.4.2 跳入保护模式161 5.4.3 重新放置...

Global site tag (gtag.js) - Google Analytics