(译)win32asm教程-2
(译)win32asm教程-2 3.0 asm基础知识
这章将教你汇编语言的基础知识
1. 1伪代码(opcodes)
汇编程序是用伪代码创建的。一个伪代码是一条处理器可以理解的指令。例如:
ADD
Add指令把两个数加到一起。大部分伪代码有参数
ADD eax, edx
ADD有两个参数。在加法的情况下,一个源一个目标。它把源值加到目标值中,并把结果保存在目标中。参数有很多不同的类型:寄存器,内存地址,直接数值(immediate values)如下:
3. 2寄存器
有几种大小的寄存器:8位,16位,32位(在MMX处理器中有更多)。在16位程序中,你仅能使用16位和8位的寄存器。在32位的程序中,你可以使用32位的寄存器。
一些寄存器是别的寄存器的一部分:例如,如果EAX保存了值EA7823BBh这里是其他寄存器的值。
EAX
EA
78
23
BB
AX
EA
78
23
BB
AH
EA
78
23
BB
AL
EA
78
23
BB
Ax,ah,al是eax的一部分。Eax是一个32位的寄存器(仅在386以上存在),ax包含了eax的低16位(2字节),ah包含了ax的高字节,而al包含了ax的低字节。因而ax是16位的,al和ax是8位的。在上面的例子中,这些是那些寄存器的值:
eax = EA7823BB (32-bit)
ax = 23BB (16-bit)
ah = 23 (8-bit)
al = BB (8-bit)
使用寄存器的例子(不要管那些伪代码,只看寄存器的说明)
mov eax, 12345678h
Mov把一个值载入寄存器(注意:12345678h是一个十六进制值,因为h这个后缀。
mov cl, ah
把ax的高字节移入cl
sub cl, 10
从cl的值中减去10(十进制)
mov al, cl
并把cl存入eax的最低字节
让我们来分析上面的代码:
mov指令可以把一个值从寄存器,内存和直接数值移入另一个寄存器。在上面的例子中,eax包含了12345678h,然后ah的值(eax左数第三个字节)被复制入了cl中(ecx寄存器的最低字节)。然后,cl减10并移回al中(eax的最低字节)
寄存器的不同类型:
全功能(General Purpose)
这些32位(它们的组成部分为16/8位)寄存器可以用来做任何事情:
eax (ax/ah/al)
加法器
ebx (bx/bh/bl)
基(base)
ecx (cx/ch/cl)
计数器
edx (dx/dh/dl)
数据
虽然它们有名字,但是你可以用它们做任何事。
段(Segment)寄存器
段寄存器定义了哪一段内存被使用。你可能在win32asm中用不着它们,因为windows有一个平坦(flat)的内存系统。在Dos中,内存被分为64kb的段,因而如果你想要定一个内存地址。你指定一个段,并用一个offset(偏移址)(像0172:0500(segment:offset))。在windows中,段有4GB的大小,所以你在Windows中不需要段。段总是16位寄存器。
CS
代码段
DS
数据段
SS
栈段
ES
扩展段
FS (only 286+)
全功能段
GS (only 386+)
全功能段
指针寄存器
实际上,你可以把指针寄存器当作全功能寄存器来使用(除了eip),只要你保存并恢复它们的原始值。指针寄存器之所以这么叫是因为它们经常被用来存储内存地址。一些伪代码(movb,scasb等)也要用它们。
esi (si)
源索引
edi (di)
目标索引
eip (ip)
指令指针
EIP(在16位编程中为ip)包含了指向处理器将要执行的下一条指令的指针。因而你不能把eip当作全功能寄存器来用。
栈寄存器
有2个栈寄存器:esp和ebp。Esp装有内存中当前栈的位置(在下章中,对此有更多的内容)。Ebp在函数中被用成指向局部变量的指针。
esp (sp)
栈指针
ebp (bp)
基(base)指针