汇编跳转指令使用总结

虽然jmp指令提供了控制转移,但是它不允许进行任何复杂的判断。80x86条件跳转指令提供了这种判断。条件跳转指令是创建循环和实现其他条件执行语句。条件跳转指令检查一个或多个标志位,判断它们是否匹配某个特殊条件(就像setcc指令):如果标志匹配成功,该指令就将控制转移到目标位置;如果匹配失败,CPU忽略该条件跳转指令而继续执行下一条指令。条件跳转指令有一个限制:目标标号的位置必须在跳转指令本身附近32768字节范围内,这通常对应着8000~32000条机器指令。一般情况下不会超过这种限制。

用自己的话总结:条件跳转指令是指jz,jg..等等指令,这些指令跳转方式是根据标志位的状态进行跳转,而设置这些标志的常见指令为cmp和test指令,所以他们经常搭配使用(应该是必须的)。即跳转指令前一行要吗有cmp指令要吗有test指令。

汇编标志位:

标志名                          标志 1              标志 0

OF (溢出标志)                 OV                  NV

DF  (方向标志)                                         UP                  DN

IF (中断标志)                 DI                  EI

SF (符号标志位)               PL                  NG

ZF (零标志)                   NZ                  ZR

AF (辅助进位标志位)           NA                  AC

PF (奇偶标志)                 PO                  PE

CF (进位标志)                 NC                  CY

反汇编窗口,对应的标志位(双击后面的数字可改变其状态)

Test和cmp指令的区别

test属于逻辑运算指令
Test对两个参数(目标,源)执行AND逻辑操作,并根据结果设置标志寄存器,结果本身不会保存。
举例:
Test的一个非常普遍的用法是用来测试一方寄存器是否为空:
test ecx, ecx
jz somewhere
如果ecx为零,设置ZF零标志为1,Jz跳转

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

CMP属于算术运算指令
CMP比较.(两操作数作减法,仅修改标志位,不回送结果). 
cmp实际上是只设置标志不保存结构的减法,并设置Z-flag(零标志).
举例:
Cmp eax, 2;       如果eax-2=0即eax=2就设置零标志为1
Jz ****;          如果设置了零标志就跳转

============================================

得出的结论
test逻辑与运算结果为零,就把ZF(零标志)置1;
cmp 算术减法运算结果为零,就把ZF(零标志)置1.


指 令


描 述


条 件


别 名


相 反 指 令


JC


如果进位位被置位则跳转


进位标志=1


JB,JNAE


JNC


JNC


如果进位位没有置位则跳转


进位标志=0


JNB,JAE


JC


JZ


如果0标志被置位则跳转


0标志=1


JE


JNZ


JNZ


如果0标志没有置位则跳转


0标志=0


JNE


JZ


指 令


描 述


条 件


别 名


相反指令


JS


如果符号位被置位则跳转


符号标志=1


JNS


JNS


如果符号位没有被置位则跳转


符号标志=0


JS


JO


如果溢出标志置位则跳转


溢出标志=1


JNO


JNO


如果溢出标志没有置位则跳转


溢出标志=0


JO


JP


如果奇偶校验位被置位则跳转


奇偶校验标志=1


JPE


JNP


JPE


如果奇偶校验位为偶校验则跳转


奇偶校验标志=1


JP


JPO


JNP


如果奇偶校验位没有被置位则跳转


奇偶校验标志=0


JPO


JP


JPO


如果奇偶校验位为奇校验则跳转


奇偶校验标志=0


JNP


JPE

使用无符号数比较的JCC指令


指 令


描 述


条 件


别 名


相反指令


JA


如果超过(>)则跳转


进位标志=0,0标志=0


JNBE


JNA


JNBE


如果不低于或等于(不 <=)则跳转


进位标志=0,0标志=0


JA


JBE


JAE


如果超过或等于(>=)则跳转


进位标志=0


JNC,JNB


JNAE


JNB


如果不低于则跳转(不 <)


进位标志=0


JNC,JAE


JB


JB


如果低于(<)则跳转


进位标志=1


JC,JNAE


JNB


JNAE


如果不超过或等于(不>=)则跳转


进位标志=1


JC,JB


JAE


JBE


如果低于或等于(<=)则跳转


进位标志=1或0标志=1


JNA


JNBE


JNA


如果不超过(不>)则跳转


进位标志=1或0标志=1


JBE


JA


JE


如果相等(=)则跳转


0标志=1


JZ


JNE


JNE


如果不相等(<>)则跳转


0标志=0


JNZ


JE

使用有符号数比较的JCC指令


指 令


描 述


条 件


别 名


相反指令


JG


如果大于(>)则跳转


符号标志=溢出标志或0标志=0


JNLE


JNG


JNLE


如果小于或等于(<=)则跳转


符号标志=溢出标志或0标志=0


JG


JLE


JGE


如果大于或等于(>=)则跳转


符号标志=溢出标志


JNL


JGE


JNL


如果不小于(不<)则跳转


符号标志=溢出标志


JGE


JL


JL


如果小于(<)则跳转


符号标志<>溢出标志


JNGE


JNL


JNGE


如果大于或等于(>=)跳转


符号标志<>溢出标志


JL


JGE


JLE


如果小于或等于(<=)跳转


符号标志<>溢出标志或0标志=1


JNG


JNLE


JNG


如果不大于(不>)则跳转


符号标志<>溢出标志或0标志=1


JLE


JG


JE


如果等于(=)则跳转


0标志=1


JZ


JNE


JNE


如果不等于(<>)则跳转


0标志=0


JNZ


JE

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2020-01-23

汇编语言常见错误信息中文注解

本文的目标是收集大部分汇编中常见错误信息及对其的中文注解,方便大家在写汇编程序时能够快速地定位错误并解决问题. ml.exe错误信息: 复制代码 代码如下: FATAL   严重错误 cannot open file不能打开文件 I/O error closing fileI/O错误 正在关闭文件 I/O error writing fileI/O错误 正在写文件 I/O error reading file            I/O错误 正在读取文件 out of memory      

从汇编看c++的默认析构函数的使用详解

c++中,如果没有为一个类提供析构函数,那么编译器会为这个类提供默认的析构的函数.由于析构函数的功能和构造函数相反,因此和默认的构造函数类似,编译器也会提供无用的默认的析构函数,和非无用的析构函数.两者的分析情况一样(对于默认的构造函数分析,请参看<从汇编看c++中默认构造函数的使用分析>).并且编译器会提供非无用的默认析构函数情形和默认构造函数类似: 1 类含有虚成员函数(类继承自虚基类或者继承的基类含有虚成员函数,也属于这种情况) 2 类继承自一个基类,基类含有自定义析构函数(如果基类没有

从汇编看c++中默认构造函数的使用分析

c++中的源程序: 复制代码 代码如下: class X {private:    int i;}; int main() {    X x;} 上面的类X没有定义构造函数,仅仅有一个int i. 下面为其汇编程序: 复制代码 代码如下: ; 7    : int main() { push    ebp;ebp为一个寄存器,总是指向一个函数调用堆栈的栈底,作为基址,用偏移量来访问该调用栈上的变量,但这里没有任何变量要访问,因此不起作用     mov    ebp, esp;这两句的作用是为了

汇编语言无效指令错误概述

问题:cmpxchg8b 指令比较一个8字节值edx和EAX带有8字节值内存( 目的地操作数). 只有有效目标操作数用于此指令是内存 操作数. 如果目标操作数是一个寄存器处理器应产生一个 无效OpCode例外,执行的指令cmpxchg8b应当停止和 处理器应该执行无效OpCode异常处理程序. 此错误发生是 锁定前缀为使用cmpxchg8b指令与一个(无效)寄存器目的地 操作数. 在这种情况下,处理器可能无法启动执行无效OpCode 异常处理程序,因为总线已锁定. 这将导致系统挂起. 提示:如果

汇编语言rep movsd 的使用详解

mov esi,offset @s1mov edi,offset @s2 mov ecx,10cld rep movsd 1.rep movsd 每次ecx!=0便执行movsd ,然后ecx=ecx-1 movsd移动ds:[si] 到es:[di],在32位汇编下可以用esi代替si,edi代替di 2.同时由于在一般exe中ds = es 程序起始位置所以另esi = offset @s1就可以找到变量s1 ,edi= offset @s2就可以找到变量s2 3.movsd此类指令有个性质

汇编语言 口算异或xor小结

复制代码 代码如下: 123 145 167 189 1AB 1CD 1EF 246 257 28A 29B 2CE 2DF 347 356 38B 39A 3CF 3DE 48C 49D 4AE 4BF 58D 59C 5AF 5BE 68E 69F 6AC 6BD 78F 79E 7AD 7BC

汇编语言超浓缩教程

所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩DEBUG,有时CRACK出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样).某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了.为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ--).但是想在啰里吧嗦的教科书中完成上述目标,谈何容易,所以本人整理了这篇超浓缩(用WINZIP.WINRAR-依次压迫,嘿嘿!

从汇编看c++函数的默认参数的使用说明

在c++中,可以为函数提供默认参数,这样,在调用函数的时候,如果不提供参数,编译器将为函数提供参数的默认值.下面从汇编看其原理. 下面是c++源码: 复制代码 代码如下: int add(int a = 1, int b = 2) {//参数a b有默认值    return a + b;}int main() {   int c= add();//不提供参数 } 下面是mian函数里面的汇编码: 复制代码 代码如下: ; 4    : int main() { push    ebp    m

Python中函数及默认参数的定义与调用操作实例分析

本文实例讲述了Python中函数及默认参数的定义与调用操作.分享给大家供大家参考,具体如下: #coding=utf8 ''''' Python中的函数使用小括号调用.函数在调用之前必须先定义. 如果函数中没有return语句,就会自动返回None对象. Python是通过引用调用的.如果函数内对参数的改变会影响到原始对象. 只有可变对象会受此影响,对不可变对象,它的行为类似按值调用. ''' ''''' 定义函数: def function_name([arguments]): "option

深入解析C++中的函数模板和函数的默认参数

C++函数模板 我们知道,数据或数值可以通过函数参数传递,在函数定义时它们是未知的,只有在发生函数调用时才能确定其值.这就是数据的参数化. 其实,数据类型也可以通过参数来传递,在函数定义是可以不指明具体的数据类型,当发生函数调用时,编译器可以根据传入的参数自动确定数据类型.这就是数据类型参数化. 所谓函数模板,实际上是建立一个通用函数,其返回值类型和形参类型不具体指定,用一个虚拟的类型来代替(实际上是用一个标识符来占位).这个通用函数就称为函数模板(Function Template).凡是函数

C++中函数的默认参数详细解析

使用方法:(1)在函数声明或定义时,直接对参数赋值,该参数就是默认参数.(2)在函数调用时,省略部分或全部参数,这时就会使用默认参数进行代替. 注意事项:(1)一般在声明函数是设置默认参数. 如果在函数声明和定义函数时都设置了默认参数,则以函数声明的默认参数为准. 复制代码 代码如下: #include<iostream>using namespace std;int main(){ double add(double a=3.2,double b=9.6);//在函数声明时设置默认参数 co

Python函数的默认参数设计示例详解

在Python教程里,针对默认参数,给了一个"重要警告"的例子: def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print(f(3)) 默认值只会执行一次,也没说原因.会打印出结果: [1] [1, 2] [1, 2, 3] 因为学的第一门语言是Ruby,所以感觉有些奇怪. 但肯定的是方法f一定储存了变量L. 准备知识:指针 p指向不可变对象,比如数字.则相当于p指针指向了不同的内存地址. p指向的是可变对象,

解析C++函数的默认参数和占位参数及较之C语言的拓展

可以将占位参数与默认参数结合起来使用 意义: 为以后程序的扩展留下线索 兼容C语言程序中可能出现的不规范写法 //C++可以声明占位符参数,占位符参数一般用于程序扩展和对C代码的兼容 int func(int a, int b, int = 0) { return a + b; } void main() { //如果默认参数和占位参数在一起,都能调用起来 func(1, 2); func(1, 2, 3); system("pause"); } 默认参数对C的函数拓展 1.C++中可

了解JavaScript函数中的默认参数

前言 JavaScript函数可以有默认参数值.通过默认函数参数,你可以初始化带有默认值的正式参数.如果不初始化具有某些值的参数,则该参数的默认值为undefined. 请看下列代码: function foo(num1){ console.log(num1); } foo(); 在调用函数foo时,你没有传递任何参数,因此变量num1的默认值设置为undefined.但是,有时你可能需要设置默认值而非undefined.过去,最好的策略是测试参数值undefined,然后分配一个值.所以,在上

C++语法中的函数重载和默认参数

C语言中没有函数重载 C++语言中有函数重载 函数名相同,参数个数不同.参数类型不同.参数顺序不同 例如下面就是函数重载 void sum(int a, int b){ cout << a+b << endl; } void sum(int a, double b){ cout << a+b << endl; } 返回值类型与函数重载无关 返回值类型与函数重载无关,下面代码不构成重载,编译会报错 //返回值类型与函数重载无关 int func(){ retu

C++默认参数与函数重载及注意事项

一.默认参数 在C++中,可以为参数指定默认值.在函数调用时没有指定与形参相对应的实参时, 就自动使用默认参数. 默认参数的语法与使用: (1)在函数声明或定义时,直接对参数赋值.这就是默认参数: (2)在函数调用时,省略部分或全部参数.这时可以用默认参数来代替. 注意: (1)默认参数只可在函数声明中设定一次.只有在没有函数声明时,才可以在函数定义中设定.(#add ,此句意为存在函数声明和定义两部分的时候.验证表明有这个限制,可以随便,但出于规范,在声明中指定) (2)如果一个参数设定了缺省

Python中的默认参数详解

文章的主题 不要使用可变对象作为函数的默认参数例如 list,dict,因为def是一个可执行语句,只有def执行的时候才会计算默认默认参数的值,所以使用默认参数会造成函数执行的时候一直在使用同一个对象,引起bug. 基本原理 在 Python 源码中,我们使用def来定义函数或者方法.在其他语言中,类似的东西往往只是一一个语法声明关键字,但def却是一个可执行的指令.Python代码执行的时候先会使用 compile 将其编译成 PyCodeObject. PyCodeObject 本质上依然