之前看过x86架构,最近看了ARM。发现两者的区别还是很大的。就寻址而言,ARM没有分段机制,只是分页;X86是分段+分页,所以更复杂。所以,想比较一下这两种架构。先从X86的寄存器开始说。
下面的一些内容是转载并整理的。
时下主流的汇编语言的汇编器,有以下几款:
MASM:是微软公司开发的汇编编译器,采用Intel规定的汇编语法,在6.0版本以前单独发布,分masm.exe和link.exe。从6.0版开始MASM就改名ML了,因为它把编译和链接组合在一起了。9.0版的ML跟随VC2008一起发布。以前我们在学校学的就是这个家伙。TASM:是Borland公司开发的汇编编译器,被广泛用于Turbo C,Quick Basic等编译器,用作中间过渡编译。它也能独立的编译纯汇编或是Win32Asm的代码。具有编译快速,高效的特点。TASM完全兼容MASM。由于头文件和库不完整,在win32下使用TASM有些力不从心,Borland公司目前已放弃了对其的维护和开发。
FASM:Flat Assembler,是一个纯粹用汇编语言写成,并采用自展技术的编译器。优点是不需要链接直接可以生成可执行文件。
NASM:(Netwide Assembler),是Linux 平台上一个经常用到的汇编器,由Netwide公司开发。NASM是以可移植性和模块化为目标,以支持80x86为基础而设计的编译器,它提供了很好的宏指令功能,支持多种目标文件格式,包括Linux和NetBSD、FreeBSD操作系统的a.out、ELF、COFF等文件格式,以及微软公司16位OBJ和32位OBJ文件格式;它也可以输出无格式的二进制文件(如Dos.COM,.sys)。它的语法格式很简单且易于理解,与Intel规定的很相似但却没有那么复杂。NASM 采用的是人工编写的语法分析器,因而执行速度要比 GAS 快很多,更重要的是它使用的是 Intel 汇编语法,可以用来编译用 Intel 语法格式编写的汇编程序。
GAS:(GNU Assembler), 这是Linux 平台的标准汇编器 ,它也是 GCC 所依赖的后台汇编工具,通常包含在 binutils 软件包中。GAS 使用标准的 AT&T 汇编语法(和Intel的标准语法有些区别),可以用来汇编用 AT&T 格式编写的程序。GCC会保证提供给它绝对正确的代码,所以GAS的错误检测功能相当弱。
80x86CPU,其内部的寄存器可以分为以下几类: 通用寄存器 、 专用寄存器 、 段寄存器
x86的CPU其特性都是前向兼容,所以32位的寄存器可以兼容16位和8位,16位的寄存器可以兼容8位。也就是说,32位CPU可以只使用其低16位,将它作为16位CPU来对待;16位CPU可以将其高8位和低8位分开,当作两个8位CPU来使用。当要注意,有些寄存器是不能这样分开使用的,后面我们会提到。

这八个寄存器,除了它们自己本职的工作以外,还可以用来暂存和传送数据。也就是说当我们自己写底层汇编代码时可以用着几个寄存器来临时保存数据,然后实现我们特定的功能。以我们最熟悉的系统调用为例。在汇编层面,系统调用的实现机制和处理逻辑如下:
第一步,将系统调用号(不懂什么系统调用号请猛击这里)num暂存到eax寄存器:mov eax, num
第二步,将传递给系统调用的参数依次按顺序放到ebx,ecx,edx,esi,edi这些寄存器里;
第三步,触发0x80软中断,陷入内核执行系统调用:int 80h
第四步,函数的返回值保存在eax中。
亘古不变的例子“hello world”。我们用write系统调用向标准输出设备打印该字串:- ;hello.asm
- section .data ;数据段开始
- msg db “hello,world!”,0xA; 定义要显示的字符串
- len equ $