汇编
@H_404_3@32位cpu所含有的寄存器有:@H_404_3@
4个数据寄存器(EAX、EBX、ECX和EDX)@H_404_3@
对低16位数据的存取,不会影响高16位的数据。这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的cpu中的寄存器相一致。@H_404_3@
4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可@H_404_3@
独立存取。
@H_404_3@
寄存器EAX通常称为累加器(Accumulator)@H_404_3@ @H_404_3@用累加器进行的操作可能需要更少时间。可用于乘、 除、输入/输出等操作,使用频率很@H_404_3@
高;@H_404_3@
寄存器EBX称为基地址寄存器(Base Register)@H_404_3@它可作为存储器指针来使用;@H_404_3@
寄存器ECX称为计数寄存器(Count Register) @H_404_3@
在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数;@H_404_3@
寄存器EDX称为数据寄存器(Data Register) @H_404_3@在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址@H_404_3@
注意:@H_404_3@在16位cpu中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,@H_404_3@
在32位cpu中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,@H_404_3@
@H_404_3@
2个变址和指针寄存器(ESI和EDI) @H_404_3@
其低16位对应先前cpu中的SI和DI,对低16位数据的存取,不影响高16位的数据。@H_404_3@
寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量@H_404_3@,@H_404_3@
用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。@H_404_3@
2个指针寄存器(ESP和EBP)@H_404_3@
其低16位对应先前cpu中的BP和SP,对低16位数据的存取,不影响高16位的数据。32位cpu有2个32位通用寄存器EBP和ESP。它们主要用于访问堆栈内的存储单元。寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,@H_404_3@为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。@H_404_3@
EBP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据 @H_404_3@
ESP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶@H_404_3@@H_404_3@@H_404_3@
6个段寄存器(ES、CS、SS、DS、FS和GS)段寄存器@H_404_3@
段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成@H_404_3@
的,这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。@H_404_3@
cpu内部的段寄存器:@H_404_3@
ECS——代码段寄存器(Code Segment Register),其值为代码段的段值; @H_404_3@
EDS——数据段寄存器(Data Segment Register),其值为数据段的段值; @H_404_3@
EES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值; @H_404_3@
ESS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值; @H_404_3@
EFS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值; @H_404_3@
EGS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。@H_404_3@
1个指令指针寄存器(EIP)@H_404_3@
指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。@H_404_3@
1个标志寄存器(EFlags)@H_404_3@
1、进位标志CF(Carry Flag)@H_404_3@
进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。使用该标志位的情况有:多字(字节)数的加减运算,无符号数的大小比较运算,移位操作,字(字节)之间移位,专门改变CF值的指令等。@H_404_3@
2、奇偶标志PF(Parity Flag)@H_404_3@@H_404_3@
奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。利用PF可进行奇偶校验检查,或产生奇偶校验位。在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位。@H_404_3@@H_404_3@
@H_404_3@@H_404_3@
3、辅助进位标志AF(Auxiliary Carry Flag)@H_404_3@@H_404_3@
在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:@H_404_3@@H_404_3@
(1)、在字操作时,发生低字节向高字节进位或借位时;@H_404_3@@H_404_3@
(2)、在字节操作时,发生低4位向高4位进位或借位时。@H_404_3@@H_404_3@
对以上6个运算结果标志位,在一般编程情况下,标志位CF、ZF、SF和OF的使用频率较高,而标志位PF和AF的使用频率较低。@H_404_3@@H_404_3@
@H_404_3@@H_404_3@
4、零标志ZF(Zero Flag)@H_404_3@@H_404_3@
零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。@H_404_3@@H_404_3@
@H_404_3@@H_404_3@
5、符号标志SF(Sign Flag)@H_404_3@@H_404_3@
符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。@H_404_3@@H_404_3@
@H_404_3@@H_404_3@
6、溢出标志OF(Overflow Flag)@H_404_3@@H_404_3@
溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。@H_404_3@@H_404_3@
“溢出”和“进位”是两个不同含义的概念,不要混淆。如果不太清楚的话,请查阅《计算机组成原理》课程中的有关章节。@H_404_3@@H_404_3@
@H_404_3@@H_404_3@
二、状态控制标志位@H_404_3@@H_404_3@
状态控制标志位是用来控制cpu操作的,它们要通过专门的指令才能使之发生改变。@H_404_3@@H_404_3@
1、追踪标志TF(Trap Flag)@H_404_3@@H_404_3@
当追踪标志TF被置为1时,cpu进入单步执行方式,即每执行一条指令,产生一个单步中断请求。这种方式主要用于程序的调试。@H_404_3@@H_404_3@
指令系统中没有专门的指令来改变标志位TF的值,但程序员可用其它办法来改变其值。@H_404_3@@H_404_3@
2、中断允许标志IF(Interrupt-enable Flag)@H_404_3@@H_404_3@
中断允许标志IF是用来决定cpu是否响应cpu外部的可屏蔽中断发出的中断请求。@H_404_3@@H_404_3@
但不管该标志为何值,cpu都必须响应cpu外部的不可屏蔽中断所发出的中断请求,以及cpu内部产生的中断请求。@H_404_3@@H_404_3@
具体规定如下:@H_404_3@@H_404_3@
(1)、当IF=1时,cpu可以响应cpu外部的可屏蔽中断发出的中断请求;@H_404_3@@H_404_3@
(2)、当IF=0时,cpu不响应cpu外部的可屏蔽中断发出的中断请求。@H_404_3@@H_404_3@
cpu的指令系统中也有专门的指令来改变标志位IF的值。@H_404_3@@H_404_3@
3、方向标志DF(Direction Flag)@H_404_3@@H_404_3@
方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。具体规定在第5.2.11节——字符串操作指令——中给出。@H_404_3@@H_404_3@
在微机的指令系统中,还提供了专门的指令来改变标志位DF的值。@H_404_3@@H_404_3@
汇编指令:@H_404_3@
常用@H_404_3@
MOV 传送字或字节. @H_404_3@
MOVSX 先符号扩展,再传送. @H_404_3@
MOVZX 先零扩展,再传送. @H_404_3@
PUSH 把字压入堆栈. @H_404_3@
POP 把字弹出堆栈. @H_404_3@
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈. @H_404_3@
POPA 把DI,AX依次弹出堆栈. @H_404_3@
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈. @H_404_3@
POPAD 把EDI,EAX依次弹出堆栈.@H_404_3@
XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数) @H_404_3@
CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX ) @H_404_3@
XADD 先交换再累加.( 结果在第一个操作数里 )@H_404_3@
ADD 加法. @H_404_3@
ADC 带进位加法. @H_404_3@
INC 加 1. @H_404_3@
AAA 加法的ASCII码调整. @H_404_3@
DAA 加法的十进制调整. @H_404_3@
SUB 减法. @H_404_3@
SBB 带借位减法. @H_404_3@
DEC 减 1. @H_404_3@
NEC 求反(以 0 减之). @H_404_3@
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果). @H_404_3@
AAS 减法的ASCII码调整. @H_404_3@
DAS 减法的十进制调整. @H_404_3@
MUL 无符号乘法. @H_404_3@
IMUL 整数乘法. @H_404_3@
AAM 乘法的ASCII码调整. @H_404_3@
DIV 无符号除法. @H_404_3@
IDIV 整数除法. @H_404_3@
AAD 除法的ASCII码调整. @H_404_3@
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去) @H_404_3@
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去) @H_404_3@
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去) @H_404_3@
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)@H_404_3@
逻辑运算指令 @H_404_3@
AND 与运算. @H_404_3@
OR 或运算. @H_404_3@
XOR 异或运算. @H_404_3@
NOT 取反. @H_404_3@
TEST 测试.(两操作数作与运算,不回送结果). @H_404_3@
SHL 逻辑左移. @H_404_3@
SAL 算术左移.(=SHL) @H_404_3@
SHR 逻辑右移. @H_404_3@
SAR 算术右移.(=SHR) @H_404_3@
ROL 循环左移. @H_404_3@
ROR 循环右移. @H_404_3@
RCL 通过进位的循环左移. @H_404_3@
RCR 通过进位的循环右移.@H_404_3@
程序转移指令 @H_404_3@
1.简单的条件转移指令 @H_404_3@
JZ(或jE) OPR---------------结果为零转移,测试条件ZF=1 @H_404_3@
JNZ(或jNE) OPR --------------结果不为零转移,测试条件ZF=0 @H_404_3@
JS OPR----------------------结果为负转移,测试条件SF=1 @H_404_3@
JNS OPR---------------------结果为正转移,测试条件SF=0 @H_404_3@
JO OPR--------------------- 溢出转移,测试条件OF= @H_404_3@
JNO OPR --------------------不溢出转移,测试条件SF=0 @H_404_3@
JP OPR ---------------------结果为偶转移,测试条件SF=1 @H_404_3@
JNP OPR --------------------结果为奇转移,测试条件SF=0 @H_404_3@
JC OPR -------------------- 有进位转移,测试条件SF=1 @H_404_3@
JNC OPR --------------------无进位转移,测试条件SF=0@H_404_3@
2.无符号比较条件转移指令(以下指令经常是CMP OPD,OPS后面的指令根据比较结果来实现转移) @H_404_3@
JB(或JNAE) opd --------------小于或者不大于等于则转移 @H_404_3@
JNB(或JAE) opd---------------不小于或者大于等于则转移 @H_404_3@
JA(或NJBE) OPD---------------大于或者不小于等于则转移 @H_404_3@
JNA(或JBE) OPD---------------不大于或者小于等于则转移@H_404_3@
3.带符号比较条件转移指令 @H_404_3@
JL(或JNGE) --------------小于或者不大于等于则转移 @H_404_3@
JNL(或JGE)--------------不小于或者大于等于则转移 @H_404_3@
JG(或NJLE)---------------大于或者不小于等于则转移 @H_404_3@
JNG(或JLE)---------------不大于或者小于等于则转移 @H_404_3@
调用子程序与返回指令 @H_404_3@
CALL 子程序调用指令 @H_404_3@
RET 子程序返回指令 @H_404_3@
其它指令 @H_404_3@
OFFSET -------------------- 返回偏移地址 @H_404_3@
SEG -------------------- 返回段地址 @H_404_3@
EQU(=) -------------------- 等值语句 @H_404_3@
PURGE -------------------- 解除语句 @H_404_3@
DUP -------------------- 操作数字段用复制操作符 @H_404_3@
SEGMENT,ENDS -------------------- 段定义指令 @H_404_3@
ASSUME -------------------- 段地址分配指令 @H_404_3@
ORG -------------------- 起始偏移地址设置指令 @H_404_3@
$ --------------------地址计数器的当前值 @H_404_3@
PROC,ENDP -------------------- 过程定义语句 @H_404_3@
NAME,TITLE,END -------------------- 程序开始结束语句 @H_404_3@
MACRO,ENDM --------------------宏定义指令 @H_404_3@
XLAT (TRANSLATE) -------------------- 换码指令---- @H_404_3@
条件标志 @H_404_3@
ZF 零标志 -- 当结果为负时,SF=1,否则,SF=0. @H_404_3@
AF 辅助进位标志---运算过程中第三位有进位值,置AF=1,AF=0 @H_404_3@
PF 奇偶标志------当结果操作数中偶数个"1",置PF=1,PF=0 @H_404_3@
SF 符号标志----当结果为负时,SF=1;否则,SF=0.溢出时情形例外 @H_404_3@
CF 进位标志----- 最高有效位产生进位值,例如,执行加法指令时,MSB有进位,置CF=1;否则,CF=0.@H_404_3@
OF 溢出标志-----若操作数结果超出了机器能表示的范围,则产生溢出,置OF=1,OF=0@H_404_3@
OllyDbg 常用快捷热键@H_404_3@
打开一个新的可执行程序 (F3)@H_404_3@
重新运行当前调试的程序 (Ctrl+F2)@H_404_3@
当前调试的程序 (Alt+F2)@H_404_3@
运行选定的程序进行调试 (F9)@H_404_3@
暂时停止被调试程序的执行 (F12)@H_404_3@
单步进入被调试程序的 Call 中 (F7)@H_404_3@
步过被调试程序的 Call (F8)@H_404_3@
跟入被调试程序的 Call 中 (Ctrl+F11)@H_404_3@
跟踪时跳过被调试程序的 Call (Ctrl+F12)@H_404_3@
执行直到返回 (Ctrl+F9)@H_404_3@
显示记录窗口 (Alt+L)@H_404_3@
显示模块窗口 (Alt+E)@H_404_3@
显示内存窗口 (Alt+M)@H_404_3@
显示 cpu 窗口 (Alt+C)@H_404_3@
显示补丁窗口 (Ctrl+P)@H_404_3@
显示呼叫堆栈 (Alt+K)@H_404_3@
显示断点窗口 (Alt+B)@H_404_3@
打开调试选项窗口 (Alt+O)@H_404_3@
F9 使用方法:@H_404_3@
Ctrl+F9 运行至ret
Alt+F9 运行至上层调用的下句
Shift+F9 忽略异常运行@H_404_3@
BTW:Ollydbg.hlp有中文翻译版为何不看?@H_404_3@
Shift+F9 - 与F9相同,但是如果被调试程序发生异常而中止,调试器会首先尝试执行被调试程序指定的异常处理(请参考忽略@H_404_3@
Kernel32中的内存非法访问)。@H_404_3@
Ctrl+F9 - 执行直到返回,跟踪程序直到遇到返回,在此期间不进入子函数也不更新cpu数据。因为程序是一条一条命令执行的,所@H_404_3@
以速度可能会慢一些。按Esc键,可以停止跟踪。@H_404_3@
Alt+F9 - 执行直到返回到用户代码段,跟踪程序直到指令所属于的模块不在系统目录中,在此期间不进入子函数也不更新cpu数据。@H_404_3@
因为程序是一条一条执行的,所以速度可能会慢一些。按Esc键,可以停止跟踪。@H_404_3@
F9@H_404_3@ - 让程序继续执行。
Shift+F9 - 与F9@H_404_3@相同,但是如果被调试程序发生异常而中止,调试器会首先尝试执行被调试程序指定的异常处理(请参考忽略Kernel32中的内存非法访问)。
Ctrl+F9@H_404_3@ - 执行直到返回,跟踪程序直到遇到返回,在此期间不进入子函数也不更新cpu数据。因为程序是一条一条命令执行的,所以速度可能会慢一些。按Esc键,可以停止跟踪。
Alt+F9@H_404_3@ - 执行直到返回到用户代码段,跟踪程序直到指令所属于的模块不在系统目录中,在此期间不进入子函数也不更新cpu数据。因为程序是一条一条执行的,所以速度可能会慢一些。按Esc键,可以停止跟踪。
Ctrl+F11@H_404_3@ -Run跟踪步入,一条一条执行命令,进入每个子函数调用,并把寄存器的信息加入到Run跟踪的存储数据中。Run跟踪不会同步更新cpu窗口。
F12@H_404_3@ - 停止程序执行,同时暂停被调试程序的所有线程。请不要手动恢复线程运行,最好使用继续执行快捷键或菜单选项(像 F9)。
Ctrl+F12@H_404_3@ - Run跟踪 步过,一条一条执行命令,但是不进入子函数调用,,并把寄存器的信息加入到Run跟踪的存储数据中。Run跟踪不会同步更新cpu窗口。
Esc@H_404_3@ - 如果当前处于自动运行或跟踪状态,则停止自动运行或跟踪;如果cpu显示的是跟踪数据,则显示真实数据。
Alt+B@H_404_3@ - 显示断点窗口。在这个窗口中,您可以编辑、删除、或跟进到断点处。
Alt+C@H_404_3@ - 显示cpu窗口。
Alt+E@H_404_3@ - 显示模块列表[list of modules]。
Alt+K@H_404_3@ - 显示调用栈[Call stack]窗口。
Alt+L@H_