补码条件跳转指令
Posted chenxingyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了补码条件跳转指令相关的知识,希望对你有一定的参考价值。
补码(二进制:正数的补码为本身,负数的补码为取反加一)
12进制时钟:
12 + 1 = 13 = 1
12 - 11 = 1
这里的1和-1就互为补码
计算器将减法运算转换为加法运算简化电路
如果是正数,补码为其本身
如果是负数,补码即为摸减去这个数的绝对值
1 --> 1
-11 --> 12 - 11 --> 1
128 - 1 = 128 + (-1的补码) = 128 + (128 - 1) = 128 + 127 = 127
取反加一的由来(设为8位)
值范围为-2^7 ~ 2^7 - 1,模为 2^7(0111 1111 + 0000 0001)
值为x
2^7 - |x| ==> 0111 1111 - |x|[对x除最高位(最高位为取绝对值置零了)取反] + 1
8 位二进制数有符号取值范围为 -2^7 ~ 2^7 - 1
原码根据是否有符号(最高位是否为1)则为 -127 ~ 127 其中0有两个 1000 0000(-0) 和 0000 0000(+0)
补码
正数(为原码)
+127 0111 1111
+126 0111 1110
...
+1 0000 0001
0 0000 0000
负数(符号位不变,其他取反加一)
-1 1000 0001 --> 1111 1111
-2 1000 0010 --> 1111 1110
-3 1000 0011 --> 1111 1101
...
-126 1111 1110 --> 1000 0010
-127 1111 1111 --> 1000 0001
-128 XXXX XXXX --> 1000 0000
那么-128 的原码是什么呢,由补码求原码相同 1000 0000 -> 1000 0000(低七位运算时产生溢出,舍去溢出位1)
XXXX XXXX = -128 = 1000 0000
这样就只有一个零了
CF 进位标志位(0-255)(最高位是否发生变化)
无符号运算是否发生进位/借位
255 - 67 = 1111 1111 - 0100 0011 = 10111100 ==> 未发生进位与借位
67 - 255 = 0100 0100 ==> 最高位发生了借位
SF 符号标志位(-126~127)(即最高位是否为1)
最高位是否为1
未溢出时
-1 - (-2) = 1111 1111 + 0000 0010 = (1) 0000 0001 ---> SF = 0, 前者大于后者
-2 - (-1) = 1111 1110 + 0000 0001 = 1111 1111 ---> SF = 1, 前者小于后者
OF 溢出标志位(结果超出了有符号数所能表示的范围)
有符号数运算结果是否发生溢出
溢出时(负数减正数、正数减负数)
-3-126 = 1111 1101 + 1000 0010 = 0111 1111 ---> SF = 0, OF = 1 ---> 前者小于后者
3 - (-126) = 3 + 126 = 129 > 127 ---> SF = 1, OF = 1 ---> 前者大于后者
-3-125 ---> SF = 1, OF = 0 --->前者小于后者
3 - (-124) ---> SF = 0, OF = 0 --->前者大于后者
无符号数的比较
<1 CF = 0 ---> 前者大于等于后者
<2 CF = 1 ---> 前者小于后者
带符号数比较
<1 OF = 0, SF = 0 / OF = 1, SF = 1 ---> 前者大于等于后者
<2 OF = 0, SF = 1 / OF = 1, SF = 0 ---> 前者小于后者
<3 即 OF⊕SF = 1 ---> 前者小于后者; OF⊙SF = 1 ---> 前者大于等于后者
CMP实现两无符号大小比较时,条件转移涉及A(Above)、B(Below)、E(Equal), 包括JA(JNBE)、JAE(JNB)、JB(JNAE)、JBE(JNA)
用SUB实现两个无符号数大小比较时,涉及CF的条件转移指令JC、JNC
CMP实现两有符号大小比较时,条件转移指令涉及G(Greater)、L(Less)、E(Equal), 包括JG(JNLE)、JGE(JNL)、JL(JNGE)、JLE(JNG)
用SUB实现两有符号大小比较时,涉及SF与OF的条件转移指令JS、JNS、JO、JNO
JMP无条件转移
JMP
指令的相对转移都是近转移
JMP NEAR PTR 标号
JMP SHORT PTR 标号
JMP FAR PTR 标号 (段间转移)
12进制时钟:
12 + 1 = 13 = 1
12 - 11 = 1
这里的1和-1就互为补码
计算器将减法运算转换为加法运算简化电路
如果是正数,补码为其本身
如果是负数,补码即为摸减去这个数的绝对值
1 --> 1
-11 --> 12 - 11 --> 1
128 - 1 = 128 + (-1的补码) = 128 + (128 - 1) = 128 + 127 = 127
取反加一的由来(设为8位)
值范围为-2^7 ~ 2^7 - 1,模为 2^7(0111 1111 + 0000 0001)
值为x
2^7 - |x| ==> 0111 1111 - |x|[对x除最高位(最高位为取绝对值置零了)取反] + 1
8 位二进制数有符号取值范围为 -2^7 ~ 2^7 - 1
原码根据是否有符号(最高位是否为1)则为 -127 ~ 127 其中0有两个 1000 0000(-0) 和 0000 0000(+0)
补码
正数(为原码)
+127 0111 1111
+126 0111 1110
...
+1 0000 0001
0 0000 0000
负数(符号位不变,其他取反加一)
-1 1000 0001 --> 1111 1111
-2 1000 0010 --> 1111 1110
-3 1000 0011 --> 1111 1101
...
-126 1111 1110 --> 1000 0010
-127 1111 1111 --> 1000 0001
-128 XXXX XXXX --> 1000 0000
那么-128 的原码是什么呢,由补码求原码相同 1000 0000 -> 1000 0000(低七位运算时产生溢出,舍去溢出位1)
XXXX XXXX = -128 = 1000 0000
这样就只有一个零了
CF 进位标志位(0-255)(最高位是否发生变化)
无符号运算是否发生进位/借位
255 - 67 = 1111 1111 - 0100 0011 = 10111100 ==> 未发生进位与借位
67 - 255 = 0100 0100 ==> 最高位发生了借位
SF 符号标志位(-126~127)(即最高位是否为1)
最高位是否为1
未溢出时
-1 - (-2) = 1111 1111 + 0000 0010 = (1) 0000 0001 ---> SF = 0, 前者大于后者
-2 - (-1) = 1111 1110 + 0000 0001 = 1111 1111 ---> SF = 1, 前者小于后者
OF 溢出标志位(结果超出了有符号数所能表示的范围)
有符号数运算结果是否发生溢出
溢出时(负数减正数、正数减负数)
-3-126 = 1111 1101 + 1000 0010 = 0111 1111 ---> SF = 0, OF = 1 ---> 前者小于后者
3 - (-126) = 3 + 126 = 129 > 127 ---> SF = 1, OF = 1 ---> 前者大于后者
-3-125 ---> SF = 1, OF = 0 --->前者小于后者
3 - (-124) ---> SF = 0, OF = 0 --->前者大于后者
无符号数的比较
<1 CF = 0 ---> 前者大于等于后者
<2 CF = 1 ---> 前者小于后者
带符号数比较
<1 OF = 0, SF = 0 / OF = 1, SF = 1 ---> 前者大于等于后者
<2 OF = 0, SF = 1 / OF = 1, SF = 0 ---> 前者小于后者
<3 即 OF⊕SF = 1 ---> 前者小于后者; OF⊙SF = 1 ---> 前者大于等于后者
CMP实现两无符号大小比较时,条件转移涉及A(Above)、B(Below)、E(Equal), 包括JA(JNBE)、JAE(JNB)、JB(JNAE)、JBE(JNA)
用SUB实现两个无符号数大小比较时,涉及CF的条件转移指令JC、JNC
CMP实现两有符号大小比较时,条件转移指令涉及G(Greater)、L(Less)、E(Equal), 包括JG(JNLE)、JGE(JNL)、JL(JNGE)、JLE(JNG)
用SUB实现两有符号大小比较时,涉及SF与OF的条件转移指令JS、JNS、JO、JNO
JMP无条件转移
JMP
指令的相对转移都是近转移
JMP NEAR PTR 标号
JMP SHORT PTR 标号
JMP FAR PTR 标号 (段间转移)
13
84756
以上是关于补码条件跳转指令的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )
Android 逆向x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )