知识点:
条件转移指令JNE/JNZ
ZF(零标志)
不等于转移指令 JNE/JNZ (等于JE/JZ)
1、 JNE/JNZ功能
条件转移指令JNE/JNZ //不等于转移
格式: JNE/JNZ 标号
功能: ZF=0,转至标号地址处执行
2、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| printf("begin\n");
int a=4;
//if (a==3) //ZF=0
//{
// printf("未跳转ZF==1\n");
//}
//printf("ZF==0跳转\n");
__asm
{ mov eax,3
sub eax,a //3-4
jz end; //ZF=1
}
printf("未跳转\n");
end:
printf("跳转\n");
printf("end\n");
getchar();
00401004 |. 68 F4204000 PUSH JNE_JNZ.004020F4 ; /format = "begin\n"
00401009 |. FF15 A4204000 CALL DWORD PTR DS:[<&MSVCR90.printf>] ; \printf
0040100F |. 83C4 04 ADD ESP,4
00401012 |. C745 FC 04000>MOV DWORD PTR SS:[EBP-4],4 ; a=4
00401019 |. B8 03000000 MOV EAX,3 ; eax=3
0040101E |. 2B45 FC SUB EAX,DWORD PTR SS:[EBP-4] ; 3-4 cmp eax,[ebp-4]
00401021 |. 74 0E JE SHORT JNE_JNZ.00401031
00401023 |. 68 FC204000 PUSH JNE_JNZ.004020FC ; /format = "未跳转"
00401028 |. FF15 A4204000 CALL DWORD PTR DS:[<&MSVCR90.printf>] ; \printf
0040102E |. 83C4 04 ADD ESP,4
00401031 |> 68 04214000 PUSH JNE_JNZ.00402104 ; /format = "跳转"
00401036 |. FF15 A4204000 CALL DWORD PTR DS:[<&MSVCR90.printf>] ; \printf
0040103C |. 83C4 04 ADD ESP,4
0040103F |. 68 0C214000 PUSH JNE_JNZ.0040210C ; /format = "end\n"
00401044 |. FF15 A4204000 CALL DWORD PTR DS:[<&MSVCR90.printf>] ; \printf
0040104A |. 83C4 04 ADD ESP,4
0040104D |. FF15 9C204000 CALL DWORD PTR DS:[<&MSVCR90.getchar>] ; MSVCR90.getchar
|
知识点:
无条件跳转指令jmp
goto指令
优化后的指令
一、GOTO与JMP
无条件跳转指令
格式: JMP A
- 其中A为转移的目的地址。程序转移到目的地址所指向的指令继续往下执行。
// JZ/JE JNZ/JNE 都需要一个条件,条件成立才跳转,而jmp不需要。
- 本组指令对标志位无影响.
3、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13
| //goto jmp
printf("begin\n");
goto end;
printf("do this");
end:
printf("end\n");
getchar();
|
二、优化后的指令
/0d 禁用优化
/01 最小化大小
/02 最大化速度
/0x 完全优化
优化功能对嵌入汇编代码的程序无效
撤销对汇编指令更改
ALT+BACKSPACE键

知识点:
条件转移指令 JNGE
条件转移指令 JL
一、指令格式
条件转移指令 JL/JNGE
格式: JL/JNGE 标号地址
功能: 小于/不大于等于时转移 标号地址
JNGE 有符号 不大于等于 则跳转 //Jump if Not Greater or Equal
JL 有符号 小于 则跳转 //Jump if Less
SF=1; 符号标志位为1 则跳转到标号地址执行
二、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| printf("begin\n");
//>=
int a=0xA;
int b=0x20;
//if (a>=b) //jl
//{
// printf("do this");
//}
__asm
{
mov ebx,b
sub a,ebx
jnge end
mov ebx,ebx
jl end
}
//<
end:
printf("end\n");
|
知识点:
条件转移指令 JLE
条件转移指令 JNG
一、指令格式
条件转移指令 JLE/JNG
格式: JLE/JNG 标号地址
功能: 小于等于/不大于 时转到标号地址
JNG 有符号 不大于 则跳转 //Jump if Not Greater
JLE 有符号 小于等于 则跳转 //Jump if Less or Equal
SF=1,ZF=1,OF=1 //其中一个或者多个为1 则跳转
二、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| {
printf("begin\n");
int a=3;
int b=5;
if (a>b) //JLE/JNG 小于等于/不大于时转移
{
printf("do this");
}
//JNG 不大于
printf("end;\n");
return 0;
}
|
OD ctrl+* 设置下一条要执行指令的地址 简单的说就是设置EIP
JNC 指令:Jump Not Carry 没进位时跳转 //CF=0
JC ;进位则跳转 CF=1
知识点:
条件转移指令 JG(> 时转移)
条件转移指令 JNLE(<=时不转移)
条件转移指令 JGE(>=时转移)
条件转移指令JNL(<时不转移)
一、指令格式
1 2 3 4
| JG/JNLE 标号地址 不<= //大于 > // ZF=0 && SF=0 && OF=0
JGE/JNL 标号地址 不< //大于等于 >= ZF=1 || SF=0 || OF=0时跳转
|
JG : Jump if Greater // > 跳
JNLE:Jump if Not Less or Equal //不<= 跳
JGE :Jump if Greater or Equal // >= 跳
JNL: Jump if Not Less //不< 跳
二、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| printf("begin\n");
int a=4;
//if (a<=3)
//if (!(a>3))
//
//{
// printf("小于等于");
//}//大于时跳转//不小于等于跳转
__asm
{
cmp a,3
JNLE end //JG end
}
printf("do this\n");
printf("小于等于");
end:
printf("end");
return 0;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| JMP //014 JE/JZ //= //012 Jump if Equl JNE/JNZ //不= //013
//带符号数条件转移指令 JL /JNGE //不>= //小于 < //015 JLE/JNG //不> //小于等于<= //016 JG/JNLE //不<= //大于 >//017 JGE/JNL //不< //大于等于>= //017
Jump 跳转/转移 Not 不 Equal 相等 Zero 零 Less 小于 Greater 大于
|
知识点:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 二、代码测试 JE/JZ != 不跳转 JNZ/JNE == 不跳转 JG/JNLE <= 不跳转 JGE/JNL < 不跳转 JL/JNGE >= 不跳转 JLE/JNG > 不跳转 printf("begin\n"); //unsigned int a=3,b=5; if (a!=b) //je if (a==b) //jnz if (a<=b) //jg if (a<b) //jge if (a>=b) //jl if (a>b)//jle { printf("do if"); } printf("end"); return 0;
|
知识点:
JA (> 时转移)
JNBE(<=时不转移)
JA与JG的区别

Above 高于
Below低于
一、无符号大于转移指令JA/JNBE
JA : 高于 时跳转 // >时跳转
JNBE: 不低于等于 时跳转 //<=时不跳转
CF(进位标志位):当执行一个加法(减法)运算时,最高位产生进位(或借位)时,CF为1,否则为0。
ZF零标志位:若当前的运算结果为零,则ZF为1,否则为0。
JA与JG区别:
JG是带符号数比较 >
JA是无符号数比较 >
二、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| //**CF(进位标志位)**
printf("begin\n");
int a=3,b=-5;
unsigned int a2=a,b2=b;
if (a2<=b2)//无符号的生成JA 不够减 借位
if (a<=b) ///<=时不跳转>时跳转带符号的生成JG指令
{
printf("do if\n");
}
|
知识点:
JNB (不小于)
JAE (高于等于)
JNC (CF!=1)

JNB与JGE的区别
一、无符号大于转移指令JA/JNBE
JNB : 低于 时不跳转 //>=时跳转 //OD
JAE: 高于等于 时跳转 //>=时跳转
JNC :Jump Not Carry 没进位时跳转 //CF=0
JA与JG区别:
JNB 是带符号数比较 >=
JGE 是无符号数比较 >=
二、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
//CF(进位标志位)
printf("begin\n");
int a=3,b=-5;
unsigned int a2=a,b2=b;
if (a2<b2)//无符号的生成JAE JNB 不够减借位
if (a<b) ///<时不跳转>时跳转带符号的生成JGE JNL指令
{
printf("do if\n");
}
|
知识点:
JB/JNAE/JC <指令
与JL/JNGE区别
一、无符号大于转移指令JB/JNAE/JC
JB 低于 时跳转 //< 时跳转 //OD
JNAE: 高于等于 时不跳转 //**>=**时不跳转
JC :Jump Carry 进位时跳转 //CF=1
JB与JL区别:
JB 是带符号数比较 >=
JL 是无符号数比较 >=
二、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| //CF(进位标志位)
printf("begin\n");
int a=3,b=-5;
unsigned int a2=a,b2=b;
if (a2**>=** b2)//无符号的生成JAE JNB 不够减借位
if (a**>=** b) ///<时不跳转>时跳转带符号的生成JGE JNL指令
{
printf("do if\n");
}
|
知识点:
JBE/JNA <=指令
与JLE/JNG区别

一、无符号大于转移指令JBE/JNA
JBE: 低于等于 时跳转 // <=时跳转 //OD
**JNA: 高于 时不跳转 //> 不跳转 **
JBE与JLE区别:
JLE 是带符号数比较 >=
JBE 是无符号数比较 >=
二、代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
//CF(进位标志位)
printf("begin\n");
int a=3,b=-5;
unsigned int a2=a,b2=b;
if (a2>=b2)//无符号的生成JAE JNB 不够减借位
if (a>= b) ///<时不跳转>时跳转带符号的生成JGE JNL指令
{
printf("do if\n");
}
|