From:
Introduction to NASM
A Study Material for CS2093-Hadware Laboratory
国外的一份NASM学习汇编的学习资料,对于有计算机组织结构和一定编程基础,想学习NASM汇编的programmer很实用。
鉴于本人水平有限,有误之处请各位看官指出,不胜感激。
一、.计算机组成原理基础知识
这一部分讲的浅显易懂,我大致说说,都是很基础的东西。
1.处理器
处理器是计算机的大脑,它执行计算机的所有逻辑和运算操作,是真正执行程序的部件,它管理计算机资源,执行进程调度,控制计算机与外围设备之间的交互,因而实现用户提供的指令。
2.寄存器
在80X86体系架构下,有8个通用寄存器。他们包括EAX,EBX,ECX,EDX,EBP,ESI,EDI,ESP。这些寄存器的低16位是可以独立使用的,只要去掉名字开头的E字母(如:AX,AH,AL),这是为了和以前的指令集进行向下兼容(曾经寄存器是16bit甚至是8bit的)。这些通用寄存器主要用于处理器存储计算中的立即数和存储地址信息,所以也叫做暂存区域(scratchpad area)。
通常情况下,通用寄存器的功能如下:
·EAX:Accumulator Register--保存一些操作的操作数,如multiplication
·EBX:Base Register-数据段的指针,一般指向数据段的首地址
·ECX:CouterRegister-计数器,通常运于循环计数和字符串操作
·EDX:用做指向I/O端口的指针
·ESI:Source Index-源变址寄存器,用做字符串操作中的源地址指针,也可以用做指向数据段的指针(Data Segment)
·EDI:Destination Index-目的变址寄存器,字符串操作中用做目的地址指针,也可以用做多余的段地址(Extra Segment)
·ESP:Stack Pointer,总是指向栈顶
·EBP:BasePointer,总是指向栈基
·FLAGS是CPU中一些描述当前CPU状态/CPU最近执行地计算操作的状态的特殊的寄存器,有一些FLAGS位需要注意:
···CarryFlag:如果计算中有进位,此bit被置为1
···ZeroFlag:如果最近的计算结果是0,此位置为1
···SignFlag:如果最近的有符号计算结果是负的,此位置为1
···ParityFlag:如果最近的计算结果为奇数,此位置为1
···InterruptFlag:如果此位被置为1,而后它将只会监听外部中断
·EIP是指令寄存器,它指向下一个要被执行的指令
3.总线(Bus)
Bus表示一切CPU中在两个部件间传递数据的通信媒介,分为数据总线,地址总线和控制总线。
4.系统时钟(System Clock)
微处理器中最基础的单元是逻辑门,它们表示逻辑上的0和1继而表示数字,这些0、1串需要进行同步处理,所以产生了时钟,在控制总线上,有一位用于时钟。
一条指令的处理可以分为4个阶段:
取指(Fetch):取数据和指令
译码(Decode):按照指令集,解析二进制指令,决定要执行的操作
执行(Execute):执行操作
写回(Write):将结果写回内存
5.中断(Interrupts)
中断可能产生于外部源或者是内部操作,在linux系统中,80h 是OS进入中断处理例程的调用号,在windows系统中是21h。当中断发生的时候,处理器将会保存当前的上下文,然后调用ISR(中断处理例程)。
二、千里之行始于足下
1.安装NASM
官方下载NASM安装包,安装即可。
2.为什么要使用汇编语言:
·学习汇编会对系统底层机制、计算机的组成原理和程序的执行有更深刻的认识
·汇编语言的程序更加高效(当然要有一定功底之后才行)
·一些系统软件和linux内核使用汇编语言编写的,我们可以将汇编语言嵌入其中,比如使用asm()这样的函数。
3.第一个汇编程序:
当然按照惯例,从"hello world"开始
section .text
global _start;
_start:
mov eax, 4
mov ebx, 1
mov ecx, string
mov edx, length
int 80h
;exit的系统调用
mov eax, 1
mov ebx, 0
int 80h
section .data
string: db 'hello world',0Ah
length: equ 13
section .bss
var:resb 1
以下对代码做简单的说明:
(1)NASM中的段(Section)
.text段中有可执行的代码,就是通常所说的代码区
.data是数据区,声明和存放已初始化的变量,此变量是全局变量(至少对整个文件是可见的),Dx进行这些变量的初始化。
.bss是声明未初始化的变量,RESx用于给这些变量预留空间。
String:string db "hello"和String2: db "H","e","l","l"."o"是等价的
TIMES:用于初始化array,每个元素为同一个值
Eg: var: times 100 db
(2)在NASM中取地址中存储的值必须要使用'[ ]'表示取内容。
其余的部分,将在后续的指令集部分进行详细的说明,这篇就到这里,Thx!