精华内容
下载资源
问答
  • 汇编语言cmp指令
    万次阅读
    2020-09-11 23:45:48

         cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。

    其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

    cmp指令格式:cmp 操作对象1,操作对象2

    例如:
    指令cmp ax, ax,做(ax)-(ax)的运算,结果为0,但并不在ax中保存,仅影响flag的相关各位。
    指令执行后:zf=1,pf=1,sf=0,cf=0,of=0。

    CPU在执行cmp指令的时候,也包含两种含义:进行无符号数运算和进行有符号数运算。

     

     

    参考资料:<<汇编语言>> 王爽

    更多相关内容
  • 汇编语言 CMP指令

    万次阅读 多人点赞 2021-06-22 15:50:37
    标志位 当实际的减法发生时,CMP指令按照计算结果修改溢出、符号、零、进位、辅助进位和奇偶标志位。如果比较的是两个无符号数,则零标志位和进位标志位表示的两个操作数之间的关系如下表所示: CMP结果 ZF CF ...

    CMP(比较)指令执行从目的操作数中减去源操作数的隐含减法操作,并且不修改任何操作数。
    指令格式:

    CMP 目的操作数, 源操作数
    

    标志位 当实际的减法发生时,CMP指令按照计算结果修改溢出、符号、零、进位、辅助进位和奇偶标志位。如果比较的是两个无符号数,则零标志位和进位标志位表示的两个操作数之间的关系如下表所示:

    CMP结果ZFCF
    目的操作数 < 源操作数01
    目的操作数 > 源操作数00
    目的操作数 = 源操作数10

    如果比较的是两个有符号数,则符号标志位、零标志位和溢出标志位表示的两个操作数之间的关系如下表所示:

    CMP结果标志位
    目的操作数 < 源操作数SF ≠ OF
    目的操作数 > 源操作数SF = OF
    目的操作数 = 源操作数ZF = 1

    CMP指令是创建条件逻辑结构的重要工具。当在条件跳转指令中使用CMP时,汇编语言的执行结果就和IF语句一样。
    以下是目的操作数 < 源操作数的举例:

    			;	ZF      CF
    mov ax, 5
    cmp ax, 10	;	0       1
    

    在这里插入图片描述
    以下是目的操作数 = 源操作数的举例:

                            ;	ZF      CF
    			mov ax, 1000
    			mov cx, 1000
    			cmp cx, ax  ;   1       0
    

    在这里插入图片描述

    以下是目的操作数 > 源操作数的举例:

    			   ;ZF      CF
    mov ax, 105
    cmp ax, 0      ;0       0
    

    在这里插入图片描述
    使用CMP指令统计data 段中数值为8的字节个数,用ax保存统计结果。

    ; 1.编程 统计data 段中数值为8的字节个数,用ax保存统计结果
    assume cs:code, ds:data, ss:stack
    
    data segment
    		db 8, 11, 8, 1, 8, 5, 63, 38
    data ends
    
    stack segment stack
    		db 128 dup(0)
    stack ends
    
    code segment
    		start: mov ax, stack
    				mov ss,ax
    				mov sp, 128
    				
    				call init_reg
    				
    				call get_eight
    				
    				mov ax, 4C00H
    				int 21H
    				
    ;============================================
    get_eight:			
    				mov si,0
    				mov cx, 8
    				mov ax, 0
    				
    getEight:		cmp byte ptr ds:[si], 8
    				jne nextNumber
    				inc ax
    nextNumber:		inc si
    				loop getEight
    				
    				ret
    ;===============================================
    init_reg:		
    				mov bx, data
    				mov ds, bx
    				ret
    				
    code ends
    
    end start		
    

    在这里插入图片描述
    使用 CMP指令 统计data 段中数值大于8的字节个数,用ax保存统计结果

    ; 2.编程 统计data 段中数值大于8的字节个数,用ax保存统计结果
    assume cs:code, ds:data, ss:stack
    
    data segment
    		db 8, 11, 8, 12, 8, 5, 63, 38
    data ends
    
    stack segment stack
    		db 128 dup(0)
    stack ends
    
    code segment
    		start: mov ax, stack
    				mov ss,ax
    				mov sp, 128
    				
    				call init_reg
    				
    				call get_eight
    				
    				mov ax, 4C00H
    				int 21H
    				
    ;============================================
    get_eight:			
    				mov si,0
    				mov cx, 8
    				mov ax, 0
    				
    getEight:		cmp byte ptr ds:[si], 8
    				jna nextNumber    ; ja >   na <=
    				inc ax
    nextNumber:		inc si
    				loop getEight
    				
    				ret
    ;===============================================
    init_reg:		
    				mov bx, data
    				mov ds, bx
    				ret
    				
    code ends
    
    end start
    

    在这里插入图片描述

    CMP ax, bx修改标志位符号描述
    ax = bxZF = 1相等
    ax != bxZF = 0不相等
    ax < bxCF = 1小于
    ax >= bxCF = 0大于等于
    ax > bxCF = 0 并且 ZF = 0大于
    ax <= bxCF = 1 或者 ZF = 1小于等于

    基于有符号的举例:

    mov al, 1
    mov bl, 2
    cmp al, bl  →  推理出来 al < bl
    sub al, bl  →  影响标志位        1 - 2 = -1    SF 符号标志位置1
    
    mov al, 22H →    34    34 - (-96) = 140    -128 ~ 127
    mov bl, A0H      -96
    sub al, bl  →   OF标志位   和 SF标志位     溢出标志位置1    符号标志位置1
    
    mov al, 8AH    -118 - 112   =  - 230  溢出   1A 正数
    mov bl, 70H
    cmp al, bl           OF = 1  SF  = 0    溢出标志位置1   符号标志位置0
    

    总结:基于有符号比较

    设 cmp al, bl
    如果 SF = 1  OF = 0
    那么 al < bl
    
    如果SF = 1 OF =1
    那么 al > bl
    
    如果 SF = 0 OF = 1     
    因为 SF = 0
    不等式应该为 al - bl > 0    al > bl        
    当OF = 1 成立时,那么
    al < bl
    
    如果SF = 0 OF = 0    
    那么 al - bl > 0 
    得到 al > bl
    

    如果因为溢出导致了实际结果为负,那么逻辑上真正的结果必然为正。

    如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负。

    基于无符号数比较的跳转

    助记符说明
    JB小于跳转
    JNB不小于跳转
    JNBE不小于或等于跳转
    JA大于跳转
    JNA不大于跳转
    JNAE不大于或等于跳转

    基于相等性的跳转

    助记符说明
    JE相等跳转
    JNE不相等跳转
    JCXZCX = 0 跳转
    JECXZECX = 0 跳转
    JRCXZRCX = 0 跳转(64模式)

    基于有符号数比较的跳转

    助记符说明
    JG大于跳转
    JL小于跳转
    JNLE不小于或等于跳转
    JNGE不大于活等于跳转
    JGE大于或等于跳转
    JLE小于或等于跳转
    JNL不小于跳转
    JNG不大于跳转

    基于进位和零标志位的跳转

    助记符说明
    JC进位跳转(进位标志位置1)
    JNC无进位跳转(进位标志位清零)
    JZ为零跳转(零标志位置1)
    JNZ非零跳转(零标志位清零)
    展开全文
  • 汇编语言,补码

    复习背景

    事情是这样的:cmp指令配合SF和OF两个标志寄存器进行逻辑上的判断。可这个判断下面,会涉及二进制数据间的加减,而加减又要区分有符号、无符号情况,以及存储的规律。于是,我在补码知识上的欠缺让整个学习过程摇摇欲坠

    分析"三码"

    原码众所周知,不再赘述。

    反码

    反码的意义:

    在计算机的数字电路中只有加法器,没有所谓的“减法器”。不是说计算机厂商不会设计减法器,因为聪明的人既然发明了方法能够用加法来实现减法操作,那为什么还需要画蛇添足的弄一个减法器?

    示例:3+[-5]=[-2]的计算过程为:
    [0_0000011]+[1_1111010]=[1_11111101]

    补码

    补码的出现是因为“0”。

    00000000和11111111分别表示 +0和-0,可0作为一个数据,不能有两种表现方式而引起矛盾。所以+0被保留了下来,而-0的归处则是同其他负数 一起增加1位,从-0~ -127 变为 -1 ~ -128 。
    关于这一点:

    1. 这是为什么同一内存空间的数据范围,负数绝对值的最值要比正数大1。
    2. 这也是补码是反码+1的原因。
    3. 这也解释了:-128为什么没有原码、反码。

    至此,通过补码就成功解决了数字0在计算机中非唯一编码的问题,且也能实现减法变加法。

    一个比方:
    反码就是讨巧了数位循环,好比时钟一圈12小时,往后拨5小时与往前拨7小时是等效的;而现在换成1个字节,一整圈以255为循环(+0和-0重叠),-5和+250等效。补码的意义就是把0的重叠问题解决了,一整圈以256为循环,-5和+251等效。

    所以,在计算机的世界里,0是正数。这点和我们学的数学不一样。

    {0_1111111}=+127 (补码)

    {0_0000000}=+0 (补码)

    {1_1111111}=-1 (补码)

    {1_0000000}=-128 (补码)

    扩展:

    1. 减法变加法只是CPU的一个运算过程,它并不会去修改参与运算数存储的值,你可以理解为CPU从BX里面把5取出来之后,有专门的电路负责把它变成-5的补码,然后再参与加法运算。BX的值是我们人为赋予的5,当然不能为了做这样一个减法而随意去修改它。

    2. 计算机真正的编码过程,不需要考虑和判断所谓的第一位正负号“符号位”,只要看到符号“-”就重复“反码+1”的取相反数过程。

    3. 配合 2 来说,补码就是一种取相反数的机制,这种相反数的机制使计算机在底层算术运算时不需要人为判断符号位。但在抽象层高了以后的操作中,像输出到屏幕API、printf语句等,会由编译器来判断符号位。

      例如,对一个编码0xF0,当它存储在内存中的时候,如果是无符号数,应等于240;如果是有符号数,应等于-16。那它究竟是代表哪个数呢?计算机在硬件层面并不需要知道它代表的是240还是-16,因为它是正是负都不影响和别的任何数字做加减操作。比如在与数字2的编码值0x02相加之后,编码值是0xF2,那这个编码值就可以代表是242或-14

    4. 乘除法的过程,符号位会参与运算。因为符号位参与了计算过程,因此你在做乘除法之前,就必须在硬件层面指定0xF0代表的是正数240还是负数-16。正因为如此,汇编程序在做乘除法的时候,必须要指定是无符号乘除还是有符号乘除,无符号除法用指令:DIV,有符号除法用指令:IDIV。

    5. 循环进位:反码的符号位相加后,如果有进位出现,则要把它送回到最低位去相加,如:3 + (-2) 和 3 +(-1)

    PS:这里存在大量摘录,(同时更详细的实现过程可以看)源网页:
    —>参考:为什么用补码

    当然,补码作为计算机能够处理的最终数据形态,将是真正存放在内存和硬盘里的数据。不信我们看下补码定义:

    在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。

    引出问题

    困扰我的问题是:
    对于同一个存储的数据,它何时作为正数补码,何时作为负数补码?

    这里我给出的解释是,底层数据中,正数补码和负数补码当然是一模一样的,也就是说计算机会把这两种情况都考虑在内,然后凭借标志寄存器(程序状态字)同时记录两种情况需要的标志。

    问题背景下,CF与OF的深入

    如:无符号情况的CF的借位,有符号情况的OF的溢出。
    (同一问题的两个方面)

    对于CF来说:

    • 进位:无符号数相加时,最高有效位向更高位进位,表示无符号数运算发生上溢出
    • 借位:无符号数相减时,最高有效位向更高位借值,表示无符号数运算发生下溢出

    对于OF来说:
    溢出是针对有符号数而言的,即运算结果超出最大范围。只有当两个相同符号数相加,而运算结果符号原数据符号相反时(MSB为符号位),产生溢出。
    (概括:溢出只会出现在两正数或负数相加的情况
    不过需要注意的是,两个负数的补码,原最高位相加后的进位由硬件自动舍出,不考虑在数据和溢出范围之内。

    —>参考:借位与溢出

    解决:回到cmp

    cmp的操作会发生溢出的情况,这种情况下,sf的值可能会产生“误导”,即cmp的比较结果只能记录实际结果的正负,不能得到真正的逻辑结果。它还需要借助OF。

    ;关于逻辑结果和实际结果:
    mov ah,08ah
    mov bh,070h
    cmp ah,bh
    ;实际结果得到1AH, 值为26 ,SF=0;
    ;逻辑结果应为(-118)-112=-230; 即包括溢出位的11AH
    ;溢出会让逻辑结果与实际结果相反。
    

    cmp要配合SF,OF。
    cmp A B :无外乎四种情况:

    • SF = 1 ,OF = 0

      OF=0没有溢出,实际结果=逻辑结果。
      SF=1,实际结果为负数。A-B<0。
      A<B

    • SF = 0 ,OF = 0

      OF=0没有溢出,实际结果=逻辑结果。
      SF=0, 实际结果为非负(正数或0)。A-B≥0。
      A≥B

    • SF = 1 ,OF = 1

      OF=1存在溢出,实际结果与逻辑结果相反。
      SF=1,实际结果为负,逻辑结果为正。A-B>0
      A>B

    • SF = 0 ,OF = 1

      OF=1存在溢出,实际结果与逻辑结果相反。
      SF=0,实际结果为正,逻辑结果为非负。A-B≤0
      A≤B

    溢出导致实际结果与逻辑结果相反的解释:这个结果是配合cmp造成的。注意cmp A B ,从运算角度看,是A-B。这个减号意味着只有A和B异号的情况才会导致溢出(即两负数或两正数加和的情况)。
    在AB异号的条件下

    • 正数加和(正减负)溢出的实际结果一定为负数。以8位内存数据为例,0~127的两个数据,溢出的情况无外乎127+1到127+127。而这个范围内的和 不会摆脱 -1 ~ -128 的补码形式。(说到这里,你想起上文提到的“循环”"钟表"例子了吗)

    • 负数加和(负减正)与之同理。

    附赠(debug模式查看标志寄存器)

    标志中文YN
    OF溢出(是/否)OV OVerflowNV Not oVerflow
    DF方向(减量/增量)DN DowNUP UP
    IF中断(允许/关闭)EI Enable InterruptDI Disable Interrupt
    SF符号(负/正)NG NeGativePL PLus
    ZF零(是/否)ZR ZeRoNZ Not Zero
    AF辅助进位(是/否)AC Auxiliary CarryNA Not Auxiliary
    PF奇偶(是/否)PE Parity EvenPO Parity Odd
    CF进位(是/否)CY CarrYNC Not Carry
    展开全文
  • 浮点数需要其它指令来比较,在《汇编语言-基于x86处理器》第12章介绍。 cmp 目标操作数,源操作数 cmp指令用目标操作数减去源操作数,根据结果来确定溢出、符号、零、进位、辅助进位和奇偶标志位,但不会真的去...

    高级语言常用的比较语句:

    if A > B ...
    while X > 0 and X < 200   ...
    if check_for_error(N) = true

    x86汇编用cmp指令比较整数,因为字符也属于整数,所以也可以使用cmp指令。浮点数需要其它指令来比较,在《汇编语言-基于x86处理器》第12章介绍。

    cmp 目标操作数,源操作数

    cmp指令用目标操作数减去源操作数,根据结果来确定溢出、符号、零、进位、辅助进位和奇偶标志位,但不会真的去改变目标操作数,仅改变了标志位。汇编的cmp指令相当于高级语言的IF语句。

    比较两个无符号数
    CMP结果ZFCF
    目的操作数 < 源操作数01
    目的操作数 > 源操作数00
    目的操作数 = 源操作数10
    比较两个有符号数
    CMP结果标志位
    目的操作数 < 源操作数SF ≠ OF
    目的操作数 > 源操作数SF=OF
    目的操作数 = 源操作数ZF=1

    mov ax, 5
    cmp ax,10     ; ZF = 0 and CF = 1
    mov ax,1000
    mov cx,1000
    cmp cx, ax        ;ZF = 1 and CF = 0
    mov si,105
    cmp si, 0        ; ZF = 0 and CF = 0

    展开全文
  • 汇编语言cmp指令用法笔记与总结

    千次阅读 2021-05-15 21:01:37
    这篇文章主要介绍了汇编语言中cmp指令用法,结合实例形式总结分析了汇编语言cmp指令基本功能、使用方法及操作注意事项,需要的朋友可以参考下本文实例讲述了汇编语言中cmp指令用法。分享给大家供大家参考,具体如下:...
  • 一、cmp 比较指令、 二、test 比较指令、 总结
  • cmp汇编指令到底是操作数1-操作数2还是操作数2-操作数1呀?为什么文章有的说是第一种有的说是第二种。
  • 汇编cmp指令

    2021-05-26 03:07:18
    首先,RAX是64位的寄存器,EAX是32位的寄存器,他们的关系如下(别处copy来的):|63..32|31..16|15-8|7-0||AH. |AL.||AX......||EAX............||RAX...................|或者用16进制这么看0x1122334455667788=====...
  • 一般这样使用,如下图:​ jcc指令根据标志位和比大小来判断条件是否成立,成立就执行跳转根据上节课学的CF PF ZF SF OF来判断,譬如JZ转移条件就是ZF=1,JNZ转移条件就是ZF=0,中间N就是相反的意思,​ 同理可推出JC JNC ...
  • 这段指令是5-5=0,但是并不是在寄存器中a改值: 还没有给ax寄存器放值之前如上图,放入ax和bx之后如下图: 这个时候再step调试一步也就是走cmp ax,bx之后变成如下: 这里可以看到ax并没有发生改变,改变的是flags: ...
  • 看过破解教程,都知道 test,cmp 是比较关键,可是我一直不清楚它们究竟是怎么比较的,最后下决心找了很多资料,和大家一起把它们弄清楚. 首先看看:状态寄存器(即标志寄存器) PSW(Program Flag)程序状态字...
  • 汇编语言指令

    2022-03-05 17:39:45
    对于这个问题,汇编语言中用以下方法处理。 1. 通过寄存器名指明要处理的数据的尺寸。 例如: 下面的指令中,寄存器指明了指令进行的是字操作是字操作: mov ax,3 mov bx,ds:[4] mov ds,ax mov ds:[1],ax inc ax add...
  • CMP指令

    千次阅读 2021-07-26 04:47:21
    CMP指令是由美国斯坦福大学提出的,英文名称是Chip multiprocessors,翻译成中文就是单芯片多处理器,也指多核心其思想是将大规模并行处理器中的SMP(对称多处理器)集成到同一芯片内,各个处理器并行执行不同的进程。...
  • 汇编语言相关指令介绍(二)

    千次阅读 多人点赞 2021-12-19 09:34:00
    特殊算数指令,跳转指令编码,访问条件编码,位置控制编码
  • 汇编语言跳转指令总结

    千次阅读 2021-08-26 14:31:21
    汇编语言跳转指令总结汇编语言跳转指令总结整数的无符号变量类型 ( Unsigned Variable Type of Integer )无符号的字符 ( Unsigned Char ) 汇编语言跳转指令总结 JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转 ...
  • 汇编cmp比较指令详解

    千次阅读 2021-11-01 12:38:23
    刚刚看到了cmp指令,一开始有点晕。后来上网找了些资料,终于看明白了,为了方便初学者,我就简单写下我的思路吧。高手绕过,谢谢! cmp(compare)指令进行比较两个操作数的大小 例:cmp oprd1,oprd2 为第一个操作...
  • 汇编cmp比较指令详解刚刚看到了cmp指令,一开始有点晕。后来上网找了些资料,终于看明白了,为了方便初学者,我就简单写下我的思路吧。高手绕过,谢谢!cmp(compare)指令进行比较两个操作数的大小例:cmp oprd1,oprd2...
  • 汇编语言指令大全

    千次阅读 2021-08-23 19:43:25
    8080汇编手册数据传输指令 ────────────────────────────── 它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据。 1。 通用数据传送指令。 MOV 传送字或字节。 MOVSX 先符号...
  • 汇编语言基本指令

    千次阅读 2020-12-22 00:15:43
    汇编语言基本指令一.机械码,又称机器码.ultraedit打开,编辑exe文件时你会看到许许多多的由0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F组成的数码,这些数码就是机器码.修改程序时必须通过修改机器码来修改exe文件.二.需要熟练...
  • 一个比较特别的指令是lea, 意思是"装入有效地址"(Load Effective Address), 它的操作数就是地址,所以lea eax,[edx-02],就是把 edx 中的值减去2再送入eax, 而不是把由[edx-02]指明的内存地址上的值放到eax....
  • 汇编语言跳转指令

    千次阅读 2019-04-07 13:52:22
    跳转指令分三类: 一、无条件跳转: JMP; 二、根据 CX、ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转)、JECXZ(ECX 为 0 则跳转); 三、根据 EFLAGS 寄存器的标志位跳转, 这个太多了. 根据标志位跳转的指令: JE ;等于则...
  • 《C语言与汇编语言对照分析》由会员分享,可在线阅读,更多相关《C语言与汇编语言对照分析(17页珍藏版)》请在人人文库网上搜索。1、可编辑游戏通常会包含各种各样的功能,如战斗系统、UI渲染、经济系统、生产系统等...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,184
精华内容 5,273
关键字:

汇编语言cmp指令