| 
 | 
 
------------------------------  
内容表 
------------------------------  
I. 介绍  
II. 寄存器  
II.a 32位寄存器  
II.b 16位寄存器  
III. 指令  
III.a JMP  
III.b MOV  
III.c Push/Pop + The Stack  
III.d alloc/label/registersymbol  
III.e Call and Ret  
III.f 其他  
IV. Array of Bytes  
V. 结尾  
VI. 人员名单/致谢词  
------------------------------  
II. 寄存器 
------------------------------  
这些也许你已经在一些脚本中看到过,它们被非常广泛的使用。有两种寄存器被使用,接下来来进行讲解。   
---------------  
II.a 32 Bit  
---------------  
首先,我将解释每个寄存器是如何得到它们的名字的,这会帮助你记住它们哪个是哪个。首先,以E开头 (如果你注意了下面,你会发现所有的寄存器都是以E开头的) 它告诉你这个寄存器是32位寄存器。而A,B,C,D的含义你看完描述就能明显得体会到了。像SI, DI, BP,SP,IP也是一样。在 EAX, EBX, ECX, EDX后面的X,他简单的表示已经没有更多的字母了。有点像一个 NOP 命令 (之后你将读到)。如果你注意了,你会发现每个32位寄存器都是3个字母。   
 
EAX: 累加器(Acculmulator register)。能够用来当存储器 
EBX: 从前, 它是个基础寄存器,但现在只是个闲着的存储器 
ECX: 计数器(Counting register)。也能用来当存储器 
EDX: 数据寄存器(Data register)。 跟之前三个一样,能用来当存储器。  
ESI: 源址变址寄存器(SourceIndex register)。 是字符串形式的指针变量,但你现在还不用担心那部分。 能够用来当存储器。  
EDI: 目的变址寄存器(DestinyIndex register)。又一次,能够当作存储器,并且是个字符串形式的指针变量, 但别担心。  
EBP: 机制指针寄存器(Base Pointer register)。 是用来临时存储ESP, 当然也可以像常规的存储器那样使用。  
ESP: 原址指针寄存器(Source Pointer register)。它在堆栈里指向寄存器和地址(这个内容待会再说)。   
EIP: 指令指针寄存器(Instruction Pointer register)。 错误的使用会使你正在试图修改的程序崩溃。  
 
--------------- 
II.b 16 Bit 
--------------- 
16位寄存器和32位寄存器很相似,他们间有两个区别。一是,32位寄存器名字是三个字母,而16位寄存器是两个字母。还有一件事就是16位寄存器比32位寄存器多但别担心。16位寄存器我们一般都用不上。 
AX: 参照 EAX 
BX: 参照EBX 
CX: 参照ECX 
DX: 参照EDX 
SI: 参照ESI 
DI: 参照EDI 
BP: 参照EBP 
SP: 参照ESP 
IP: 参照EIP 
 
---------------  
 
关于寄存器的内容还很多。 如果你想学习更多关于寄存器的只是, 那就去拜Google大神吧。 对于绝大多数的学习者来说求知欲都是很重要的。  
 
------------------------------  
III. 命令  
------------------------------  
当今,什么语言没有它自己的函数和命令呢? 与英文相比,命令像个单词,而操作代码像个句子。操作代码并不难,比如:  
 
[table][tr][td]  Code:  [/td][/tr][tr][td]  jmp 00123EAA 
关于操作代码你应该知道两点。 
 
首先, 在操作码里,一般都会有个地址或者寄存器,以及一个显而易见的命令。地址是Hex形式的,是Hexadecimal的缩写。Hexadecimal是16进制数。 就如同10进制那样。  
 
按照这种思路想一想。如同上面提到的那样,我们一般使用十进制。这就意味着我们在一个列里不能有“10”, 因为它占了两个地方。 而16进制,10至15都可以放在一个列里头。但是你会发现,“10”并没有出现在列里头。  
 
先冷静, 这是因为在Hex进制里,10是用A表示的,而11是用B,直到15是F。再往后,它就是10,然后11,直到1F, 如果超过了20(十进制)就得从15(十六进制)往后算。有个简单的转换方法就是用操作系统自带的计算器,这里不赘述了。 
 
还有,每一个地址都有它的操作码和字节码。这个字节数就是代表操作码是什么, 每一个命令都一一对应已经定义好的字节码。我知道那些常用函数的字节码是什么,如果你想知道那些字节码的话,你还是指望别人吧,推荐去拜Google大神 =)  
   
最后,想注释很方便。 要注释的话, 就把"//"放在命令后边或某块空处,然后打上你想打的。如果你不打 "//" ,那电脑就会以为你在打命令呢。 
 
现在,让我们来了解每个命令都是干啥的。 
---------------  
III.a JMP  
---------------  
JMP 命令是最常使用的命令之一 (就如同 MOV 那样, 接下来会讲)。 也许你在操作码和脚本里看到的"JMP" 不像"MOV" 那么多,那是因为 JMP 命令有很多变种。下面就是列表。   
JMP: 始终跳转(Always jump to) 
JE/JZ: 相等则跳转(Jump to if equal)  
JNE/JNZ: 不等则跳转(Jump to if not equal) 
JA: 无符号大于则跳转( Jump to if Above)  
JG: 有符号大于则跳转(Jump to if Greater)  
JNA: 无符号不大于则跳转(Jump to if not Above)  
JNG: 有符号不大于则跳转(Jump to if not Greater)  
JB: 无符号小于则跳转(Jump to if Below)  
JL: 有符号小于则跳转(Jump to if Lower)  
JNB: 无符号不小于则跳转(Jump to if not Below)  
JNL: 有符号不小于则跳转(Jump to if not Lower)  
JAE: 无符号大于等于则跳转(Jump to if Above or Equal)   
JGE: 有符号大于等于则跳转(Jump to if Greater orEqual)  
JNAE: 无符号不大于等于则跳转(Jump to if not Above orEqual (即 JB) ) 
JNGE: 有符号不大于等于则跳转(Jump to if not greaterthan or Equal (即JL) ) 
 
现在你大致了解了,应该有些疑惑。 "Jump to if greater"或者JG都是条件跳转。 条件跳转都如同它们名字所描述的那样,会在条件成立的情况下跳转。通常,都会有CMP或者其他的比较函数在上面,这个待会再提。以上大抵就是JMP的故事。   
 
---------------  
III.b MOV  
---------------  
 
前文已经提过, MOV 命令是最被广泛实用的命令,因为它是那么给力。 下面就是MOV的例子: 
 
 
  
[table][tr][td]  Code:[/td][/tr][tr][td]  mov eax,ebx 
这个的意思是 "把ebx里存的地址放到eax里"。注意在两个寄存器之间还有个逗号,而不是空格。 最开始这可能有些令人费解,但是它真的很容易,下面来好好解释一下。   
 
"Mov"是"move"的意思。 寄存器自身表示"这个寄存器里存的地址"。 基本上来说, "把ebx里存的地址放到eax的地址里面去", 这会把eax之前的值覆盖并彻底消灭掉。=D你可以通过这个方法复制ebx并把它粘贴到eax里。   
 
另一种Mov命令。 
 
  
[table][tr][td]  Code:[/td][/tr][tr][td]  mov eax,[ebx] 
这个的意思是把ebx里面的值存到eax所存的地址里,很简单, 把寄存器或者地址用[]那么一括,就表示寄存器或者地址的值了。 
下面这段代码什么效果都没有。 
 
 
 
  
[table][tr][td]  Code:[/td][/tr][tr][td]   
  push eax                      //先让eax入栈—这个待会解释  
  mov eax,[0100200A]      //把值0100200A存到eax里  
  mov [ebx],eax              //把(值0100200A) 存到ebx的值里面 
  pop eax                       //然后让eax出栈,这个也待会讲  
 |   
 
 
 
 |