13-22

知识点:

条件转移指令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

  1. 其中A为转移的目的地址。程序转移到目的地址所指向的指令继续往下执行。

// JZ/JE JNZ/JNE 都需要一个条件,条件成立才跳转,而jmp不需要。

  1. 本组指令对标志位无影响.

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键

1626276948460

知识点:

条件转移指令 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 大于

知识点:

1626339401129

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的区别

1626345077615

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)

1626345077615

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区别

1626348252959

一、无符号大于转移指令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");

​ }