- 浏览: 543575 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (231)
- 一个操作系统的实现 (20)
- 汇编(NASM) (12)
- Linux编程 (11)
- 项目管理 (4)
- 计算机网络 (8)
- 设计模式(抽象&封装) (17)
- 数据结构和算法 (32)
- java基础 (6)
- UML细节 (2)
- C/C++ (31)
- Windows (2)
- 乱七八糟 (13)
- MyLaB (6)
- 系统程序员-成长计划 (8)
- POJ部分题目 (10)
- 数学 (6)
- 分布式 & 云计算 (2)
- python (13)
- 面试 (1)
- 链接、装载与库 (11)
- java并行编程 (3)
- 数据库 (0)
- 体系结构 (3)
- C++ template / STL (4)
- Linux环境和脚本 (6)
最新评论
-
chuanwang66:
默默水塘 写道typedef void(*Fun)(void) ...
C++虚函数表(转) -
默默水塘:
typedef void(*Fun)(void);
C++虚函数表(转) -
lishaoqingmn:
写的很好,例子简单明了,将观察者模式都表达了出来。
这里是ja ...
观察者模式——Observer
一、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
发表评论
-
lea指令——一个为了方便的多余指令
2012-10-11 11:14 1815buf db 'loading ....' lea b ... -
align num
2012-09-08 11:09 1185align是个负责内存对 ... -
C++内嵌汇编(一):反汇编分析C++代码
2012-03-01 11:13 8567注:本文是“百度文库”中下载的文章^^谢谢作者 Sa ... -
loop指令
2011-07-22 10:48 5489loop 指令 格式: loop 标号 ... -
MUL、IMUL、DIV
2011-07-21 12:06 2390汇编基础一日一学习30 M ... -
堆栈操作
2011-07-21 11:22 1328(软件)堆栈:由程序 ... -
MOVZX指令
2011-07-20 09:58 4758MOVZX指令 汇编语言数据传送指令MOV的变体。 ... -
跳转指令 jmp、call、ret、retf
2011-06-10 22:42 6918JMP、CALL和RET指 ... -
lodsb、stosb(和lodsw、stosw和lodsd、stosd指令)
2011-05-27 18:12 9374lodsb、stosb(和lodsw、stosw和lodsd、 ... -
8086/8088,80286,80386的CPU寄存器
2011-05-27 18:00 28068086/8088,80286,80386的CPU寄存器 ... -
test指令
2011-05-27 11:22 3984首先我们来学习test指令 ...
相关推荐
1.我在程序包里还加入了一个简单的操作系统源码,只能显示个“Hello, OS World”,源码文件名是“boot.asm” 2.编译方法:打开nasmpath.bat文件,键入 NASM 源码文件名 -o 输出文件名 NASM是编译器名,-O是输出...
**NASM汇编语言详解** NASM(Netwide Assembler)是一种流行的、开源的、支持Intel x86架构的汇编语言编译器。它以其简单易读的语法和广泛的平台支持而受到开发者喜爱。在本文中,我们将深入探讨NASM汇编语言的基本...
**NASM汇编编译器详解** NASM(Netwide Assembler)是一款高效、功能强大的汇编语言编译器,支持多种操作系统,包括Linux和Windows。它的语法简洁明了,即使是初学者也能快速上手,这也是它受到广泛赞誉的原因之一...
**NASM汇编编译器中文手册** NASM(Netwide Assembler)是一款流行的、开源的、跨平台的汇编语言编译器,它支持多种架构,包括x86、x64、ARM等。这款编译器因其简单易用、高效且功能强大的特点,在编程领域特别是低...
以上代码展示了如何使用NASM编写一个简单的"Hello, World!"程序,通过Linux系统调用输出文本到标准输出。 总之,NASM作为一款强大的开源汇编编译器,具有广泛的适用性和高度的灵活性,无论是初学者还是资深开发者,...
下面我们将详细探讨NASM汇编器和“Hello, world!”程序的实现。 NASM全称为Netwide Assembler,是一款开源、免费的x86架构汇编器,支持多种输出格式,如Linux下的ELF、Windows下的PE等。它拥有简洁的语法,易于学习...
对于初学者,可以从简单的“Hello, World!”程序开始,逐步深入到更复杂的示例。 在使用NASM-2.08rc4时,需要注意这是一个测试版本,可能会存在一些已知或未知的问题。在正式项目中,通常推荐使用稳定版本以确保...
"NASM中文手册.pdf"是一个重要的参考资料,它详细介绍了NASM汇编器的使用方法和语法规则。手册通常会包含以下内容: 1. NASM安装:在Linux环境下,通常通过包管理器如`apt-get`或`yum`来安装NASM。 2. NASM语法:...
标题 "asm.zip_asm hello world_world" 和描述 "asm hello world test" 暗示了这个压缩包的内容与汇编语言编程有关,特别是涉及到一个简单的 "hello world" 程序的创建和测试。汇编语言是计算机编程的一种底层语言,...
在这个例子中,我们使用NASM汇编语言编写了一个简单的程序来输出“Hello, World!”。 - **编译过程**: - 首先确保已经安装了NASM汇编器。在大多数Linux发行版中,可以通过包管理器安装,例如使用`sudo apt-get ...
- 编写汇编代码,例如一个简单的"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 ...
在本文中,我们将深入探讨如何在Visual Studio 2015环境下使用NASM(Netwide Assembler)编译32位汇编语言程序。NASM是一款功能强大的、开源的汇编器,支持X86和X86_64架构,广泛应用于Windows、Linux和Mac OS等操作...
标题中的“hello nasm masm linux”表明我们将探讨与NASM、MASM汇编语言以及Linux操作系统相关的知识。这三个元素都是计算机科学和技术领域的重要组成部分,尤其是对于底层编程和系统级开发来说。 首先,我们来了解...
**NASM汇编器详解** NASM(Netwide Assembler)是一个开源、高效的汇编语言编译器,专为X86架构设计,支持多种操作系统,包括Windows、Linux、FreeBSD等。NASM的全称源于其最初的开发目标——成为网络广泛适用的...
**NASM汇编编译器介绍** NASM(Netwide Assembler)是一款开源、免费的x86架构汇编语言编译器,广泛应用于Linux、Windows以及其他多种操作系统。它支持Intel和AT&T两种语法风格,并且具有高度可移植性和易用性。...
通过编写简单的程序,如打印“Hello, World!”,逐步过渡到更复杂的任务,如内存管理、进程调度等,将有助于巩固理论知识并提升实际操作技能。 **总结** 掌握NASM汇编器对于深入学习计算机底层机制,尤其是进行...
编写完NASM源代码后,需要使用NASM汇编器将其转换为二进制目标文件。这可以通过命令行工具`nasm`完成,如`nasm -f elf32 hello.asm`。生成的目标文件通常是`.o`格式,然后需要使用链接器(如`ld`或`gcc`)将目标文件...