标题：CMP指令
CMP
CMP是由美国斯坦福大学提出的，英文名称是Chip multiprocessors,翻译成中文就是单芯片多处理器,也指多核心其思想是将大规模并行处理器中的SMP（对称多处理器）集成到同一芯片内，各个处理器并行执行不同的进程。与CMP比较， SMT处理器结构的灵活性比较突出。但是，当半导体工艺进入0.18微米以后，线延时已经超过了门延迟，要求微处理器的设计通过划分许多规模更小、局部性更好的基本单元结构来进行。相比之下，由于CMP结构已经被划分成多个处理器核来设计，每个核都比较简单，有利于优化设计，因此更有发展前途。目前，IBM 的Power 4芯片和Sun的 MAJC5200芯片都采用了CMP结构。多核处理器可以在处理器内部共享缓存，提高缓存利用率，同时简化多处理器系统设计的复杂度。
在微型计算机的汇编语言中，CMP ( compare)是其中一条指令，叫做比较指令。cmp的功能相当于减法指令，只是对操作数之间运算比较，不保存结果。cmp指令执行后，将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。[1]
使用例子如：CMP ax, bx格式CMPOPR1 , OPR2.执行操作（OPR）——（OPR）功能该指令与SUB指令一样执行减法的操作，但它并不保存运算结果，只是根据结果设置相关的条件标志位（SF、ZF、CF、OF）。CMP指令后往往跟着条件转移指令，实现根据比较的结果产生不同的程序分支的功能。
CMP指令算法
cmp是比较指令， cmp的功能相当于减法指令，只是不保存结果。cmp指令执行后，将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
比如：mov ax,8 
mov bx,3 
cmp ax,bx
执行后：ax=8,ZF=0,PF=1,SF=0,CF=0,OF=0.
通过cmp指令执行后，相关标志位的值就可以看出比较的结果。
cmp ax,bx的逻辑含义是比较ax,bx中的值。如果执行后：
ZF=1则AX=BX
ZF=0则AX！=BX
CF=1则AX<BX
CF=0则AX>=BX
CF=0并ZF=0则AX>BX
CF=1或ZF=1则AX<=BX
CPU在执行cmp指令的时候，也包含两种含义：进行无符号运算和进行有符号数运算。
cmp ah,bh
如果ah=bh则ah-bh=0所以ZF=1
如果ah≠bh则ah-bh≠0所以ZF=0
所以我们根据cmp指令执行后ZF的值，就可以知道两个数据是否相等。如果ah<bh则可能发生什么情况呢？
对于有符号数运算，在ah>bh情况下，ah-bh显然可能引起SF=1既结果为负比如：
ah=1，bh=2则ah-bh=0FFH，0FFH为-1的补码，因为结果为负，所以SF=1。
ah=0FEH，bx=OFFH；则ax-bx=-2-(-1)=OFFH,因为结果为负，所以SF=1。
再看两个例子：
ah=22H，bh=OAOH则ah-bh=34-(-96)=82H，82H是-126的补码。
所以SF=1。这里虽然SF=1，但是并不能说明ah<bh因为显然34>-96
两个有符号数A和B相减，得到的是负数，那么可以肯定A<B这个思路没有错误，关键在于我们根据什么来断定得到的是一个负数，CPU将cmp指令得到的结果记录在flag的相关标志位中，我们可以根据指令执行后，相关标志位的值来判断比较的结果。单纯的考察SF的值不可能知道结果的正负。因为SF记录的只是可以在计算机中存放的相应位数的正负，cmp ah，bh执行后，SF记录的是ah-bh所得到的8位结果数据的正负，虽然这个结果没有在我们能够使用的寄存器或内存单元中保存，但是在指令执行的过程中，它暂存在cpu内存的暂存器中。
所得到的相应结果的正负，并不能说明，运算所应该得到的结果的正负。这是因为在运算的过程中可能发生溢出。如果这样的情况发生，那么SF的值就不能说明任何问题。比如
mov ah,22H
mov bh,0A0H
sub ah,bh
结果SF=1运算实际得到的结果是ah=82H，但是在逻辑上，运算所应该得到的结果是34-（-96）=130就是因为130这个结果作为一个有符号Y数超出了-128~127这个范围，在ah中不能表示，而ah中的结果被CPU当作有符号数解释为-126。而SF被用来记录这个实际结果的正负所以SF=1
又比如
mov ah,0A0H
mov bh,0CBH
cmp ah,bh
结果SF=1，运算ah-bh实际得到的结果是D5H但是在逻辑上，运算所应该得到的结果是160- -53=213，（隐身人注：对于有符号数，方位是-128--127。所以这里正确是：(-96)-(-53)=-43,得到值为：0D5H,这里SF标志位指示并没错）SF记录实际结果的正负，所以SF=1。但SF=1不能说明在逻辑上运算所得到的正确结果。
但是逻辑上的结果的正负才是cmp指令所求的真正结果，因为我们就是要靠它得到两个操作对象的比较信息。所以cmp所做的比较结果，不是仅仅靠SF就能记录的，因为它只能记录实际结果的正负。
我们考虑下，两种结果之间的关系，实际结果的正负，和逻辑上真正结果的正负，它们之间有多大的距离呢？总上面的分析中我们知道，实际结果的正负，之所以不能说明逻辑上真正结果的正负，关键的原因在于发生了溢出。如果没有溢出发生的话，那么，实际结果的正负和逻辑上真正结果的正负就一致了。
所以我们应该在考察SF的同时考察OF旧可以得知逻辑上真正结果的正负同时就可以知道斤毫秒度的结果。
下面我们以cmp ah，bh为例总结一下CPU执行cmp指令后SF和PF的值的如何来说明比较的结果的：
1）如果SF=1而OF=0说明没有溢出逻辑上真正结果的正负=实际结果的正负，因实际结果为负所以逻辑上真正的结果为负则ah<bh
2）如果SF=1而OF=1说明实际结果为负并且有溢出，则实际结果和真正结果不等，因SF=1实际结果为负。则：如果因为溢出导致了实际结果为负。那么逻辑上真正的结果必然为正。ah<bh
3）如果SF=0而OF=1说明实际结果为正并且有溢出，则实际结果和真正结果不等，因SF=0，实际结果非负。则：如果因为溢出导致了实际结果为正，那么逻辑上真正的结果必然为负。这样说明ah<bh
4）如果SF=0而OF=0说明没有溢出，逻辑上真正结果的正负=实际结果的正负，因SF=0实际结果非负，所以逻辑上真正的结果非负，所以ah>=bh
指令集
IBM-PC汇编语言指令集
数据传送指令集
MOV
功能: 把源操作数送给目的操作数
语法: MOV 目的操作数,源操作数
格式: MOV r1,r2
MOV r,m
MOV m,r
MOV r,data
XCHG
功能: 交换两个操作数的数据
语法: XCHG
格式: XCHG r1,r2 XCHG m,r XCHG r,m
PUSH,POP
功能: 把操作数压入或取出堆栈
语法: PUSH 操作数 POP 操作数
格式: PUSH r PUSH M PUSH data POP r POP m 
PUSHF,POPF,PUSHA,POPA
功能: 堆栈指令群
格式: PUSHF POPF PUSHA POPA
LEA,LDS,LES
功能: 取地址至寄存器
语法: LEA r,m LDS r,m LES r,m
XLAT(XLATB)
功能: 查表指令
语法: XLAT XLAT m
算数运算指令
ADD,ADC
功能: 加法指令
语法: ADD OP1,OP2 ADC OP1,OP2
格式: ADD r1,r2 ADD r,m ADD m,r ADD r,data
影响标志: C,P,A,Z,S,O
SUB,SBB
功能:减法指令
语法: SUB OP1,OP2 SBB OP1,OP2
格式: SUB r1,r2 SUB r,m SUB m,r SUB r,data SUB m,data
影响标志: C,P,A,Z,S,O
INC,DEC
功能: 把OP的值加一或减一
语法: INC OP DEC OP
格式: INC r/m DEC r/m
影响标志: P,A,Z,S,O
NEG
功能: 将OP的符号反相(取二进制补码)
语法: NEG OP
格式: NEG r/m
影响标志: C,P,A,Z,S,O
MUL,IMUL
功能: 乘法指令
语法: MUL OP IMUL OP
格式: MUL r/m IMUL r/m 
影响标志: C,P,A,Z,S,O(仅IMUL会影响S标志)
DIV,IDIV 
功能:除法指令
语法: DIV OP IDIV OP
格式: DIV r/m IDIV r/m
CBW,CWD
功能: 有符号数扩展指令
语法: CBW CWD
AAA,AAS,AAM,AAD
功能: 非压BCD码运算调整指令
语法: AAA AAS AAM AAD
影响标志: A,C(AAA,AAS) S,Z,P(AAM,AAD)
DAA,DAS
功能: 压缩BCD码调整指令
语法: DAA DAS
影响标志: C,P,A,Z,S
位运算指令集
AND,OR,XOR,NOT,TEST
功能: 执行BIT与BIT之间的逻辑运算
语法: AND r/m,r/m/data OR r/m,r/m/data XOR r/m,r/m/data TEST r/m,r/m/data NOT r/m
影响标志: C,O,P,Z,S(其中C与O两个标志会被设为0) NOT指令不影响任何标志位
SHR,SHL,SAR,SAL
功能: 移位指令
语法: SHR r/m,data/CL SHL r/m,data/CL SAR r/m,data/CL SAL r/m,data/CL
影响标志: C,P,Z,S,O
ROR,ROL,RCR,RCL
功能: 循环移位指令
语法: ROR r/m,data/CL ROL r/m,data/CL RCR r/m,data/CL RCL r/m,data/CL
影响标志: C,P,Z,S,O
程序流程控制指令集
CLC,STC,CMC
功能: 设定进位标志
语法: CLC STC CMC
标志位: C 
CLD,STD
功能: 设定方向标志
语法: CLD STD
标志位: D 
CLI,STI
功能: 设定中断标志
语法: CLI STI
标志位: I
CMP
功能: 比较OP1与OP2的值
语法: CMP r/m,r/m/data
标志位: C,P,A,Z,O
JMP
功能: 跳往指定地址执行
语法: JMP 地址
JXX
功能: 当特定条件成立则跳往指定地址执行
语法: JXX 地址
注:
A: ABOVE,当C=0,Z=0时成立
B: BELOW,当C=1时成立
C: CARRY,当弁时成立 CXZ: CX寄存器的值为0(ZERO)时成立
E: EQUAL,当Z=1时成立
G: GREATER(大于),当Z=0且S=0时成立
L: LESS(小于),当S不为零时成立
N: NOT(相反条件),需和其它符号配合使用
O: OVERFLOW,O=1时成立
P: PARITY,P=1时成立
PE: PARITY EVEN,P=1时成立
PO: PARITY ODD,P=0时成立
S: SIGN,S=1时成立
Z: ZERO,Z=1时成立
LOOP
功能: 循环指令集
语法: LOOP 地址
LOOPE(Z)
地址 LOOPNE(Z) 地址
标志位: 无
CALL,RET
功能: 子程序调用,返回指令
语法: CALL 地址 RET RET n
标志位: 无
INT,IRET
功能: 中断调用及返回指令
语法: INT n IRET
标志位: 在执行INT时,CPU会自动将标志寄存器的值入栈,在执行IRET时则会将堆栈中的标志值弹回寄存器
字符串操作指令集
MOVSB,MOVSW,MOVSD
功能: 字符串传送指令
语法: MOVSB MOVSW MOVSD
标志位: 无
CMPSB,CMPSW,CMPSD
功能: 字符串比较指令
语法: CMPSB CMPSW CMPSD
标志位: C,P,Z,S,O
SCASB,SCASW
功能: 字符串搜索指令
语法: SCASB SCASW
标志位: C,P,Z,S,O
LODSB,LODSW,STOSB,STOSW
功能: 字符串载入或存贮指令
语法: LODSB LODSW STOSB STOSW
标志位: 无
REP,REPE,REPNE
功能: 重复前缀指令集
语法: REP 指令S REPE 指令S REPNE 指令S
标志位: 依指令S而定
对于IBM PC机它有它的指令系统，其中包括：数据传送指令、串处理指令、算术指令、控制移动指令、逻辑指令、处理机控制指令。
这里将简单介绍其指令类型及指令说明，如有要求给具体的指令格式及应用，请与amay联系，amay加以更新。
1)数据传送指令：负责把数据、地址或立即数传送到寄存器或存储单元中。
数据传送指令类型指　令　说　明
通用数据传送指令 MOV（传送）、PUSH（进栈）、POP（出栈）、XCHG（交换）
累加器专用传送指令 IN（输入指令）、OUT（输入指令）
地址传送指令 LEA（有效地址送寄存器）、LDS（指针送寄存器和DS）、LES（指针送寄存器和ES）
标志寄存器传送指令 LAHF（标志送AH）、SAHF（AH送标志寄存器）、PUSHF（标志进栈）、POPF（标志出栈）
2）算术指令：用来执行算术运算。
算术指令类型指　令　说　明
加法指令 ADD（加法）、ADC（带进位加法）、INC（加1）
减法指令 SUB（减法）、SBB（带借位减法）、DEC（减1）、NEG（求补）、CMP（比较）
乘法指令 MUL（无符号数乘法）、IMUL（带符号数乘法）
除法指令 DIV（无符号数除法）、IDIV（带符号数除法）、CBW（字节转换为字）、CWD（字转换为双字）
3）逻辑指令：对字或字节执行逻辑运算。
逻辑指令类型指　令　说　明
逻辑运算指令 AND（逻辑与）、OR（逻辑或）、NOT（逻辑非）、XOR（异或）、TEST（测试）
移动指令 SHL（逻辑左移）、SAL（算术左移）、SHR（逻辑右移）、SAR（算术右移）、ROL（循环左移）、ROR（循环右移）、RCL（带进位循环左移）、RCR（带进位右移）
4）串处理指令：处理存放存储器里的数据串。
串处理指令类型指　令　说　明
指　令 MOVS（串传送）、CMPS（串比较）、SCAS（串扫描）、LODS（从串取）、STOS（存入串）
5）控制转移指令：用来控制程序的执行流程。
控制转移指令类型指　令说　明
无条件转移指令 JMP（段间和段内转移）
条件转移指令 JZ（结果为0（或相等）则转移）、JS（结果为负则转移）、JNS（结果为正则转移）、JO（溢出则转移）、JNO（不溢出则转移）、JP（奇偶位为1则转移）、JNP（奇偶位为0则转移）
循环指令 LOOP（循环指令）、LOOPPZ/LOOPE（当为0或相等时循环指令）、LOOPNZ/LOOPNE（当不为0或不相等时循环指令）
子程序指令 CALL（调用指令）、RET（返回指令）
中断指令 INT（中断）、INTO（如溢出则中断）、RIET（从中断返回）
6）处理机控制指令：
处理机控制指令类型指　令　说　明
标志处理指令 CLC（进位位置0指令）、CMC（进位位求反指令）、STC（进位位置为1指令）、CLD（方向标志置1指令）、STD（方向标志位置1指令）、CLI（中断标志置0指令）、STI（中断标志置1指令）
其他处理机控制指令 NOP（无操作）、HLT（停机）、WAIT（等待）、ESC（换码）
汇编cmp比较指令详解
cmp(compare)指令进行比较两个操作数的大小
例:cmp oprd1,oprd2
为第一个操作减去第二个操作数,
但不影响第两个操作数的值
它影响flag的CF，ZF，OF，AF，PF
我们怎么判断大小呢？
若执行指令后
ZF=1 这个简单，则说明两个数相等，因为zero为1说明结果为0
当无符号时：
若
CF=1 则说明了有进位或借位，cmp是进行的减操作，故可以看出为借位，所以，此时oprd1<oprd2
CF=0 则说明了无借位，但此时要注意ZF是否为0，若为0，则说明结果不为0，故此时oprd1>oprd2
当有符号时：
若SF=0，OF=0 则说明了此时的值为正数，没有溢出，可以直观的看出，oprd1>oprd2
若SF=1，OF=0 则说明了此时的值为负数，没有溢出，则为oprd1<oprd2
若SF=0，OF=1 则说明了此时的值为正数，有溢出，可以看出oprd1<oprd2
若SF=1，OF=1则说明了此时的值为负数，有溢出，可以看出oprd1>oprd2
最后两个可以作出这种判断的原因是，溢出的本质问题：
两数同为正，相加，值为负，则说明溢出
两数同为负，相加，值为正，则说明溢出
故有，正正得负则溢出，负负得正则溢出