打印 上一主题 下一主题

[windows] 汇编初体验之逆向工程常用汇编指令汇总2

[复制链接]
跳转到指定楼层
楼主
3234 0 小黑豆share 发表于 2017-1-20 18:56:17
检测位指令TEST

检测位指令是把二个操作数进行逻辑“与”操作,并根据运算结果设置相应的标志位,但并不保存该运算结果,所以,不会改变指令中的操作数。在该指令后,通常用JE、JNE、JZ和JNZ等条件转移指令。

指令的格式:TEST  Reg/Mem, Reg/Mem/Imm

受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义)

call XXXXXXXX
test al,al/eax,eax...
je/jne...
**************************************************************************************************
循环指令本身的执行不影响任何标志位。

1、循环指令

循环指令LOOP的一般格式:

LOOP 标号
LOOPW 标号      ;CX作为循环计数器
LOOPD 标号      ;ECX作为循环计数器

....
....
inc eax
dex ebx
cmp eax,ebx
jne/je XXXX ^


求1+2+…+1000之和,并把结果存入AX中。


方法1:因为计数器CX只能递减,所以,可把求和式子改变为:1000+999+…+2+1。

       XOR AX, AX
       MOV CX, 1000D
again: ADD AX, CX ;计算过程:1000+999+…+2+1
       DEC CX
       LOOP again

方法2:不用循环计数器进行累加,求和式子仍为:1+2+…+999+1000。

       XOR AX, AX
       MOV CX, 1000D
       MOV BX, 1
again: ADD AX, BX ;计算过程:1+2+…+999+1000
       INC BX
       LOOP again

从程序段的效果来看:方法1要比方法2好。为什么?^_^
**************************************************************************************************
转移指令
转移指令是汇编语言程序员经常使用的一组指令。在高级语言中,时常有“尽量不要使用转移语句”的劝告,但如果在汇编语言的程序中也尽量不用转移语句,那么该程序要么无法编写,要么没有多少功能,所以,在汇编语言中,不但要使用转移指令,而且还要灵活运用,因为指令系统中有大量的转移指令。

转移指令分无条件转移指令和有条件转移指令两大类。

1、无条件转移指令

无条件转移指令包括:JMP、子程序的调用和返回指令、中断的调用和返回指令等。

下面只介绍无条件转移指令JMP

JMP指令的一般形式:

JMP  标号/Reg/Mem


2、条件转移指令

条件转移指令是一组极其重要的转移指令,它根据标志寄存器中的一个(或多个)标志位来决定是否需要转移,这就为实现多功能程序提供了必要的手段。微机的指令系统提供了丰富的条件转移指令来满足各种不同的转移需要,在编程序时,要对它们灵活运用。

条件转移指令又分三大类:基于无符号数的条件转移指令、基于有符号数的条件转移指令和基于特殊算术标志位的条件转移指令。

、无符号数的条件转移指令

指令的助忆符

JE/JZ
ZF=1 Jump Equal or Jump Zero

JNE/JNZ
ZF=0 Jump Not Equal or Jump Not Zero

JA/JNBE
CF=0 and ZF=0 Jump Above or Jump Not Below or Equal

JAE/JNB
CF=0 Jump Above or Equal or Jump Not Below

JB/JNAE
CF=1 Jump Below or Jump Not Above or Equal

JBE/JNA
CF=1 or AF=1 Jump Below or Equal or Jump Not Above

、有符号数的条件转移指令

指令的助忆符

JE/JZ
ZF=1 Jump Equal or Jump Zero

JNE/JNZ
ZF=0 Jump Not Equal or Jump Not Zero

JG/JNLE
ZF=0 and SF=OF Jump Greater or Jump Not Less or Equal

JGE/JNL
SF=OF Jump Greater or Equal or Jump Not Less

JL/JNGE
SF≠OF Jump Less or Jump Not Greater or Equal

JLE/JNG
ZF=1 or SF≠OF Jump Less or Equal or Jump Not Greater

、特殊算术标志位的条件转移指令

指令的助忆符
检测的转移条件 功能描述
JC
CF=1 Jump Carry

JNC
CF=0 Jump Not Carry

JO
OF=1 Jump Overflow

JNO
OF=0 Jump Not Overflow

JP/JPE
PF=1 Jump Parity or Jump Parity Even

JNP/JPO
PF=0 Jump Not Parity or Jump Parity Odd

JS
SF=1 Jump Sign (negative)

JNS
SF=0 Jump No Sign (positive)

例,已知一个字节变量char,试编写一程序段,把其所存的大写字母变成小写字母。

解:
next: …
char DB  'F'   ;变量说明

MOV AL, char
CMP AL, 'A'
JB next        ;注意:字符是无符号数,不要使用指令JL
CMP AL, 'Z'
JA next
ADD char, 20                  


1、子程序的调用和返回指令

子程序的调用和返回是一对互逆操作,也是一种特殊的转移操作。
一方面,之所以说是转移,是因为当调用一个子程序时,程序的执行顺序被改变,CPU将转而执行子程序中的指令序列,在这方面,调用子程序的操作含有转移指令的功能,子程序的返回指令的转移特性与此类似;
另一方面,转移指令是一种“一去不复返”的操作,而当子程序完后,还要求CPU能转而执行调用指令之下的指令,它是一种“有去有回”的操作。
为了满足子程序调用和返回操作的特殊性,在指令系统中设置了相应的特定指令。

1、1调用指令(CALL)
调用子程序指令的格式如下:

CALL 子程序名/Reg/Mem

子程序的调用指令分为近(near)调用和远(far)调用。如果被调用子程序的属性是近的,那么,CALL指令将产生一个近调用,它把该指令之后地址的偏移量(用一个字来表示的)压栈,把被调用子程序入口地址的偏移量送给指令指针寄存器IP即可实现执行程序的转移

如果被调用子程序的属性是远的,那么,CALL指令将产生一个远调用。这时,调用指令不仅要把该指令之后地址的偏移量压进栈,而且也要把段寄存器CS的值压进栈。在此之后,再把被调用子程序入口地址的偏移量和段值分别送给IP和CS,这样完成了子程序的远调用操作

00405600 call 00406895
00405604 ......

子程序调用指令本身的执行不影响任何标志位,但子程序体中指令的执行会改变标志位,所以,如果希望子程序的执行不能改变调用指令前后的标志位,那么,就要在子程序的开始处保护标志位,在子程序的返回前恢复标志位。

例如:

CALL  DISPLAY
;DISPLAY是子程序名
CALL  BX
;BX的内容是子程序的偏移量
CALL  WORD1
;WORD1是内存字变量,其值是子程序的偏移量
CALL  DWORD1
;DWORD1是双字变量,其值是子程序的偏移量和段值
CALL  word ptr [BX]
;BX所指内存字单元的值是子程序的偏移量
CALL  dword ptr [BX]
;BX所指内存双字单元的值是子程序的偏移量和段值

1、2返回指令(RET)
当子程序执行完时,需要返回到调用它的程序之中。为实现此功能,指令系统提供了一条专用的返回指令。其格式如下:

RET/RETN/RETF [Imm]

子程序的返回在功能上是子程序调用的逆操作。为了与子程序的远、近调用相对应,子程序的返回也分:远返回和近返回。返回指令在堆栈操作方面是调用指令的逆过程


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

推荐阅读

Archiver|手机版|小黑屋| 云夕阁 ( 湘ICP备16017785号-2 )     

返回顶部 返回列表