您的位置:首页 > 理论基础

汇编大全 【很不错~ 留着自己学习下】

2013-09-17 09:07 169 查看
1、汇编语言-寄存器

A B C D 后面带个H或L的 表示是8位寄存器

A B C D 后面带个 X 的 表示是16位寄存器

AX BX CX DX 前面带 E的 表示是32位寄存器

EAX AX寄存器:是累加器,它是算是运算的主要寄存器,此外还也可以作为乘,除法运算及输出指令的专用寄存器。

EBX BX寄存器:是基址寄存器,这个寄存器经常用于存放存储区的起始地址(基址)

ECX CX寄存器:计数寄存器,这个寄存器常用于循环操作或字符操作过程中的计数器。

EDX DX寄存器:这个寄存器经常与累加器配合,用于双字长运算,这个寄存器存放高位字,累积起存放的位字。

--------------------------------------

SP 堆栈指针寄存器

指针寄存器

BP 基址指针寄存器

SI 源变址 寄存器

变址寄存器

DI 目的变址寄存器

--------------------------------------

SP:堆栈指针寄存器 一般用于存放当前堆栈段的段内偏移地址,即栈顶地址。

BP:基址指针寄存器 一般用于提供堆栈内某个单元的偏移地址,它与SS堆栈寄存器联用,可以访问堆栈中任何一个存储单元。

SI:源变址 寄存器 一般用来确定数据段中的存储单元地址,然后根据DF标志,SI进行自动增量或自动减量。

DI:目的变址寄存器 一般与ES附加段寄存器联用,以达到附加段寄存中寻址的目的。

-----------------------------------

IP 指令指针寄存器

控制寄存器

FR 标志寄存器

-----------------------------------

IP:指令指针寄存器,是用来存放代码段中的偏移地址,一般与CS代码段寄存器一起联用,以确定下一条指令的物理地址,这个寄存器为专用寄存器,不能用于存储其他数据。

FR:标志寄存器,主要用于反映处理器的状态,和运算结果的某些特征。

----------------------------------

CS 代码段寄存器

DS 数据段寄存器

段寄存器

ES 附加段寄存器

SS 堆栈段寄存器

------------------------------------

CS 代码段寄存器:一般用于存放正在或正等待执行的程序段的段首址,其值为代码段的段值。

DS 数据段寄存器:一般用于存放正在或正等待执行的数据段的段首址,其值为数据段的段值。

ES 附加段寄存器:一般用于存放正在或正等待执行的附加段的段首址,其值为附加数据段的段值。

SS 堆栈段寄存器:一般用于存放正在或正等待执行的堆栈段的段首址,其值为堆栈段的段值。

2、汇编语言-常用指令篇

MOV指令----------------------------

例如:Mov eax,1234h

意思是把 1234h十六进制数值 传送到 eax 32位的数据寄存器里去

那么eax 的寄存器的值也就变成了1234h

mov 指令是降一个数据传送给另外一个数据地址或寄存器。

mov eax,[0069BA8C] :把0069BA8C 这个地址里的内存值传送给EAX 寄存器里去

mov eax,[eax] :把EAX寄存器里的值的内存值传给EAX

mov eax,[eax+00000114] :把EAX寄存器值 + 00000114 偏移量指向的内存地址的值传送给EAX去

sub eax,09 :

mov edx,[edp-80] :把EBP的值 -80 指向的内存地址的值传送给Edx寄存器里被[]的都是以地址表示,而不是数值

比如:

mov eax,[0069BA8C] 中 0069BA8C 被[] 这就是表示 提取 0069BA8C 这个内存地址里的值传送给EAX寄存器,EAX不会等于 0069BA8C, 而是 0069BA8C 这个内存地址里的值。

PUSH指令 ---------------------------

PUSH 入栈指令

指令格式:操作码 操作数

PUSH 操作数指令的功能是:将操作数压入到堆栈的栈项。

3种形式表达式:

1. PUSH AX :压入各种寄存器里的值入堆栈

2. PUSH 123H :压入一个直接数值入堆栈

3. PUSH [EDI+2c] :压入[寄存器+偏移量]指向的内存地址中的值入堆栈出栈指令POP

凡事看见一段反汇编子程序,有PUSH 那么在后面不远处就会有POP出栈指令。

指令格式:操作码 操作数

指令功能:将堆栈顶端的数据弹出到操作数中。

RET指令 ------------------------------

RET :返回值

一个子程序的最后一条指令,通常是RET指令。

RET指令的格式是:ret

它的功能是:这个指令一般是作为子程序的结束指令,使子程序返回。

LEA指令 ------------------------------

LEA指令:地址传送指令

指令格式:LEA AX,【BX+3】 :将 BX+3 的有效地址传送到AX寄存器里去

例如:这里的BX值 =2000H 那么这条汇编句经过这个LEA指令执行过后,那么AX寄存器里的值就是20003H。

LEA指令的功能:把一个有效地址传送到目的操作数里去。

XCHG指令 ------------------------------

XCHG指令 :交换指令格式

例如:XGHG AL,AH :将高8位的AH寄存器里的内容与低8位AL寄存器交换

指令功能:将2个操作数的内容相互交换给对方。

例如:这里的AH的值是100H AL的值是200H

那么这条汇编语句经过这个XCHG交换指令执行后,那么AH的值是200H,而AL的值就是100H

JMP指令 ------------------------------

jmp指令:无条件转移

指令格式:jmp 标号

例如:jmp 7C92E2DC :直接无条件跳转到7C92E2DC 地址,然后继续从 7C92E2DC执行下去

指令功能:无任何条件直接跳转到某个地址处

注意:如果这个指令中的标号是直接给出一个地址,那么称之为:直接转移

例如:jmp 7C92E2DC 如果这个指令中的标号是以间接的方式给出目的地址,就称之为:间接转移

例如:JMP DWORD PTR DS:[EAX]

转移的目的地址为 执行到当前时 EAX寄存器里的地址。

SUB指令 ------------------------------

SUB指令:减法

指令格式:SUB 操作数1 ,操作数2

功能:实现2个操作数相减,相减后的结果存放在目的操作(操作数1)里面

例如:SUB ESP,8 :将ESP寄存器的内容与8相减,最后结果存放在ESP寄存器里假如这里的ESP寄存器的值是10,那么就相当于 10-8=2 将结果18存放在ESP寄存器里,这条指令执行过后ESP寄存器里的值就是2.

ADD指令:加法

指令格式:ADD 操作数1,操作数2

功能:实现2个操作数相加,相加后的结果存放在目的操作(操作数1)里面

例如:ADD ESP,8 :将ESP寄存器的内容与8相加,最后结果存放在ESP寄存器里假如这里的ESP寄存器的值是10,那么就相当于 10+8=18 将结果18存放在ESP寄存器里,这条指令执行过后ESP寄存器里的值就是18.

注意:汇编格式里操作数之间分:目的操作数 和 源操作数

NOP指令 ------------------------------

NOP指令:无操作

指令格式:NOP

功能:这个指令的功能就是不操作 CALL 1234.004014B5 改成NOP无操作指令结果 、 那么这个程序执行到我们修改的NOP指令时 就不会在操作下去。

如果这是一个加法子程序: PUSH 7D0 :压入2000

PUSH 3E8 :压入1000 CALL 004014B5 执行完后这个函数返回的结果原本是3000

但是我们把这CALL指令改成了NOP指令

那么它返回的将不会再是3000而是-1或0

CALL指令 ------------------------------

CALL指令:过程调用指令在模块化程序设计中,通常程序员会把一个较大的程序,分解成若干个有独立功能的程序模块。这些独立的功能模块称之为子程序或执行过程。(代码块)

在过程中,可由调用程序调用这些子程序,而CALL指令可以实现子程序的调用。

CALL指令也通常称之为:调用指令

CALL指令可以调用同一个代码段的子程序,也可以调用另外一个代码段的子程序。 CALL过程调用指令:作用是调用指定某个子程序入口 执行那个子程序。

3、汇编语言-数据寻址篇寻址方式 ------------------------------

虽然在汇编语言中还有其他很多汇编指令,但是我们不需要把他们全部记住,因为随着以后分析数据次数不断接触。

慢慢的各种指令自然会掌握,除了学会常用的汇编指令外,我们还得学习数据的寻址方式。什么是寻址方式?我们知道汇编指令中的操作码是用来告诉CPU执行何种操作,并告诉CPU执行汇编指令中的操作数为**作对象。

通俗点来理解: 寻找方式就是寻找 操作数 或 操作数地址 的方式。与操作数与关的寻址方式有七种:

立即寻址。

寄存器寻址。

直接寻址。

寄存器间接寻址。

寄存器相对寻址。

基址加变址寻址。

相对基址加变址寻址。

学习寻址方式有什么用?

我们学习寻址方式的作用是用来分析数据的,前面学习的汇编指令只是为了能看明白分析数据时数据的传递和汇编代码含义,但我们不能只看懂数据的传递和汇编代码含义就行了,因为我们最终是要找到数据信息真正值,要知道数据的来源,还要知道数据的终点,所以要学习这7种寻址方式,学会后我们一眼就能看出哪个是我们需要的数据。

立即寻址 ------------------------------

如果在一条汇编指令中,直接给出了操作数,那么就无需去寻找它的操作数的数据来源,因为这种寻址方式称为立即寻址方式。它把直接给出的操作数称之为立即数。

立即寻址方式的特点:首先在指令中操作数2(源操作数)出现的操作数是一个立即数,并且立即数是以常量形式出现的,在机器码中可以观测到这个数。

例如:

16位汇编语言

Mov Ax,123H :立即寻址方式 AX = 1234H

Mov CX,40D :立即寻址方式 CX = 40D

32位汇编语言

Mov EAX,1234H :立即寻址方式 EAX = 1234H

Mov ECX,40D :立即寻址方式 ECX = 40D

这2行汇编代码都属于立即寻址方式,其中1234H和40D都是为立即数值。

像遇见这种形式的汇编代码,源操作数是直接给出一个数值的话,那么它的寻址方式就是立即寻址方式 如上面2行的汇编代码,AX和CX这2个16位寄存器的数据来源,和直观的就可以看出是分别来源1234H与40D。

而1234H与40D本身就是立即数值,没有任何其他的寄存器或地址再给他们赋值。所以我们就无需在查找1234H与4D的值来源于哪个寄存器或地址了,因为他们本身就一个数值。 明白什么是立即寻址方式后,看这2行代码中的AX和CX这2个寄存器的值是多少就很直观了。

总结:源操作数是一个以常理形式的立即数值 那么就是立即寻址方式,源操作数的值不来源于寄存器或内存地址赋值或提取 。

直接寻址 ------------------------------

什么是直接寻址方式?

假如在一个指令中是直接给出操作数的偏移地址,那么这种寻址方式就是直接寻址。

直接寻址方式它的特点是:

在指令中的偏移地址是被[]方括号括起来的一个常量值。如果这种寻址方式中给出的是操作数所在的数据段的偏移量,那么寻找这个操作数就需要确定操作数所在段的段首址,再

利用公式:物理地址 = 段首址 x 16D + EA来求出操作数的物理地址。

例如:

mov EAX,DS:[2000H] ;AX = (DSx16+2000H)

mov ECX,ES:[0ABCDH] ;ECX = (ESx16+ABCDH)

这2行汇编代码都是直接寻址方式,其中[2000h]与[ABCDH]都是操作数的偏移量

需要注意的是:直接地址 可以是正数也可以是负数

例如:mov bx,[-0020H]

辨别直接寻址方式的方法:

1.源操作数都是[]方括号括住 属于直接寻址方式特点

2.原操作数是一个常量值或直接地址,不是寄存器,属于直接寻址方式特点。

006DE469 - mov eax,[03DB2754] :直接寻址方式 这个就是游戏基址在CE寻找数据的基址和偏移量时,如果过程中出现了上面这条汇编代码,就是直接寻址方式。那么表示已经跟踪出了该数据的基址(起始地址)是什么了。

像上面的游戏基址是:03DB2754 这个地址通过这个例子,可见直接寻址方式是在寻找数据时经常遇见的,能让我们明白基址来源于哪?是什么?

006DE469 - A1 5427DB03 - mov eax,[03DB2754]

006DE46E - 8B 48 08 - mov ecx,[eax+08]

这2句,第一句汇编代码eax的值是直接给出了一个地址传送给eax ,并且这个地方被[]方括号括住,属于直接寻找地址。直接寻址的地址是不变的,因为它本身自己就是这个地址,没有其他寄存器或其他东西给它传递值。所以我们称之为基址(起始值),用它加上相关的偏移量就可以指向到相关的内存地址,然后我们读取指向的内存地址,就可以获取到数据信息。

寄存器寻址方式 ------------------------------

什么是寄存器寻址方式?

如果一个操作数存储在某个寄存器中,并且以寄存器的形式出现在指令中,那么这种寻址方式称之为寄存器寻址方式。

例:

mov Eax,Ebx

mov Eax,Ecx

mov Eax,Esi

以上例子的指令都属于寄存器寻址方式

因为操作数只可以分别存放在EBX,ECX,ESI寄存器里,并且以寄存器形式出现。

例:

mov EBX,5577H :立即数 5577H 送入 EBX 寄存器

mov ECX,EBX :寄存器寻址方式(符合以上寄存器寻址方式描述)

mov EAX,4CH 这3句汇编代码中的第2句,是寄存器寻址方式

因为操作数是存放在EBX寄存器里,并且以寄存器形式作为源操作数。

寄存器寻址辨别方法:

源操作数存储在某个寄存器中,并且以寄存器的形式出现在当前指令中。

执行完第二句后ECX寄存器的值是EBX的值(557H)ECX = EBX(5577H)

当执行完第三句后 操作码(也就是mov指令) 把4CH这个值传入EAX这个32位寄存器里的会是4CH 寄存器寻址方式是以寄存器来进行存放操作数的值。

mov EBX,5577H :EBX = 5577H

mov ECX,EBX :当跟踪到这步时,发现是条汇编代码属于寄存器寻址

mov EAX,4CH

那么我们在分析数据时,知道了ECX的值来源于EBX,遇见这种寄存器寻址方式时。我们就要放在EBX寄存器里的值源于哪里,然后往上代码找对EBX寄存器赋值的代码,来跟踪出最终数据起源地址。

寄存器间接寻址方式 ------------------------------

什么是寄存器间接寻址方式?

其实寄存器间接寻址方式与直接寻址方式看似有点类似,但是其实不一样。

寄存器间接寻址方式是指:将操作数的直接地址送入基址寄存器EBX或EBP,获知变址寄存器 ESI 与 EDI 这些寄存器中的任意一个寄存器里。在指令中使用这些存储了直接地址的寄存器作为操作数的地址指针,来实现操作数的提取和存储,我们就称之为寄存器间接寻址。

它的特点:

当我们看见汇编代码指令中出现了[]用方括号括起来的基址寄存器EBX或EBP或者变址寄存器ESI与EDI的任意一个寄存器时。

例:

mov EAX,[EBX]

mov EDX,[EBP]

mov ECX,[ESI]

mov EBX,[EDI]

上面这4种形式都是寄存器间接寻址方式它们符合寄存器间接寻址的特点:

1.都是寄存器被方括号[]括住

2.源操作数都是以EBX,EBP,ESI,EDI这四个寄存器其中任意一个寄存器来存储直接地址。

寄存器间接寻址方式与直接寻址方式的区别是:

寄存器间接寻址方式是在指令中给出了存放操作数直接地址的寄存器,以寄存器形式进行提取和存储操作数的直接地址。

例如:

mov EAX,[EBX] :操作数的直接地址存放在EBX寄存器里,并且以寄存器形式来给EAX进行提取存放在EBX寄存器里的操作数的直接地址。

直接寻址方式是在指令中直接给出直接地址,不以寄存器形式提取和存储操作数的直接地址。

例如:

mov EAX,[008231BA] :源操作数直接给出了直接地址,不是以寄存器存储和提取。

寄存器相对寻址 ------------------------------

寄存器相对寻址:这种寻址方式是将操作数存放在存储器中。而操作数的有效地址有EBX,EBP,ESI,EDI等4个寄存器任意一个寄存器的内容再加上指令中给出的8位或16位偏移量的和组成。这种寻址方式称之为寄存器相对寻址方式。

例如:

mov Eax,[Ebx+290H] 或 mov ECX,[ESI+12h] 这样的都是属于寄存器相对寻址方式。

辨别寄存器相对寻址方式的特点是:

寄存器相对寻址方式是:由在寄存器的间接寻址方式基础上,EBX,EBP,ESI,EDI等4个寄存器任意一个寄存器加上一个8位或16 位偏移量组成。它们相加后的结果构成操作数的有效地址。

例:

mov Eax,[Ebx+2000h]

解读:Eax 寄存器的内容 = 相加结果构成一个有效地址 =(EBX寄存器的内容 + 2000H )

mov Ecx,[Esi+12H]

解读:Ecx 寄存器的内容 = 相加结果构成一个有效地址 =(ESI寄存器的内容 + 12H )

需要注意:

寄存器相对寻址方式中,只能采用EBX,EBP,ESI,EDI这4个寄存器,其他寄存器都不允许。

005EF1D7 - mov eax,[0069BA8C]

005EF1DC - mov eax,[eax]

005EF1DE - mov eax,[eax+00000114]

第一句为:直接寻址方式

第二句为:寄存器间接寻址方式

第三句为:寄存器相对寻址方式因为它符合:由在寄存器间接寻址方式的基础上,再加上一个8位或16位的偏移量组成。

基址加变址寻址方式 ------------------------------

基址加变址寻址方式:

在指令中给出一个基址寄存器(EBX或者是EBP)和一个变址寄存器(ESI或者是EDI),它们2者的内容相加和是一个操作数的有效地址,那么这种寻址方式就是基址加变址寻址方式。

例:

mov AX, 或 mov CX,

这2句汇编代码语句都是属于基址加变址寻址方式不过这种方式属于16位汇编现在都是32位CPU ,所以用32位汇编表示。

mov EAX,[EBP+ESI] 或 mov ECX,[EBX+EDI] 采用这种寻址方式,如果说要求出操作数的物理地址的话,有2种情况进行计算求物理地址:

1.如果使用EBX作为寄存器与ESI或EDI相配合,那么计算操作数的物理地址公式为:

物理地址= DS x 16D + EBX + ESI

物理地址= DS x 16D + EBX + EDI

例如: mov EAX,[EBX+ESI] 假如:EBX = 00410000H DS = 2000 EIS = 300H

那么要计算出AX寄存器的内容,我们就可以按照公式来计算

首先将 DS 乘以 16D 再加 EBX + ESI

物理地址= 2000H x 16D +410000H +300H

计算机结果为:00430300 这个有效地址

然后在提取这个有效地址里的内存值传递给EAX。

2.如果使用EBP作为基址寄存器与ESI或EDI相配合,那么计算操作数的物理地址公式为:

物理地址 = SS x 16D + EBX + ESI

物理地址 = SS x 16D + EBX + EDI

相对基址加变址寻址 ------------------------------

相对基址加变址寻址方式:

在基础加变址寻址的基础上再加上一个8位或16位为偏移量,它们三者内容之和为操作数的有效地址,这种寻址方式称之为 相对基址加变址寻址方式

例:

mov EAX,[EBX+ESI+200H] :32位汇编语句

mov AX, :16位汇编语句
辨别相对基址加变址寻址的方法:

在基址加变址寻址方式的基础上在加上一个8位或16位的偏移量。

这种寻址方式比较少见。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息