zoukankan      html  css  js  c++  java
  • 汇编学习笔记(9)标志寄存器

    汇编语言中并没有高级语言的if、for语句,通过前面的学习,我们知道在汇编语言中通过loop来实现循环,通过call和ret来实现类似函数的功能。其实,不论是语法还是实现方式都不重要,重要的是要理解这种设计的思想以及为什么要设计这种指令。

    举个简单的例子,loop根据(CX)来控制循环次数,从语法上看很简单"loop 标号",但我们在享受这种便捷的同时可以思考一个问题"为什么要设计这种指令?""100个1相加为什么不能写100句add al,1?"答案不言自明。那么,学习一种语言、一个指令的同时就要考虑这样设计的意义,不然只是增加了单词量而已。

    随着科技的发展,出现了越来越多的编程语言,使我们眼花缭乱不知道该学习哪一种。是掌握的全而不精还是精而不全?这种问题在我看来完全是庸人自扰,任何语言的出现都是为了解决实际问题,我们学习哪种语言也要遵循这样的原则。找工作,可以学习时下流行的语言JAVA,C#;做科研,FORTRAN;数据分析,GO....

    言归正传,标志寄存器可以理解为存储指令执行结果的寄存器,它的每一个二进制为都有具体的意义。

    ZF

    记录指令执行后的结果是否为0,若结果等于0则ZF=1,结果不等于0,ZF=0.

    mov al,1    ;zf=0
    add al,al   ;zf=0
    sub al,al   ;zf=1

    PF

    记录指令执行后1的个数,这里的1是值二进制,若1的个数是奇数则pf=0,反之等于0.

    mov al,1    ;al=1d=00000001b,zf=0,pf=0
    add al,al   ;al=2d=00000010b,zf=0,pf=0
    sub al,al   ;al=0d=00000000b,zf=1,pf=1

    SF

    记录指令执行后结果是否是负数,若为负则sf=1反之等于0.既然有正负,肯定是对有符号数据的运算。

    mov al,1    ;al=1d=00000001b,zf=0,pf=0,sf=0
    add al,al   ;al=2d=00000010b,zf=0,pf=0,sf=0
    sub al,al   ;al=0d=00000000b,zf=1,pf=1,sf=0
    sub al,2    ;al=-2d=11111110b,zf=0,pf=0,sf=1

    CF

    记录数据运算时向高位的借位值或进位值,也就是溢出的情况。

    mov al,1    ;al=1d=00000001b,zf=0,pf=0,sf=0,cf=0
    add al,al   ;al=2d=00000010b,zf=0,pf=0,sf=0,cf=0
    sub al,al   ;al=0d=00000000b,zf=1,pf=1,sf=0,cf=0
    sub al,2    ;al=FEh=11111110b,zf=0,pf=0,sf=1,cf=1

    OF

    记录有符号运算时是否发生了溢出,有则OF=1反之等为0.

    mov al,98
    add al,99   ;cf=1,sf=1

    adc指令

    adc是带进位值的加法,adc ax,bx相当于执行(ax)=(ax)+(bx)+CF,有了这条指令就可以进行大数据的运算。

    ;计算1EF0001000H+2010001EF0H
    
    mov ax,001EH
    mov bx,0F000H
    mov cx,1000H
    add cx,1EF0H
    adc bx,1000H
    adc ax,0020H

    sbb指令

    带进位值的减法运算,原理同adc

    cmp指令

    cmp指令是比较指令,执行后只影响标志寄存器不影响参与比较的两个数据的值,根据标志寄存器相关值再进行后续的操作。cmp ax,ax后zf=1,pf=0,sf=0,cf=0,of=0,我们根据zf=1就可以判断(ax)=(ax).

    cmp指令可以用来做简单的条件判断,汇编提供了相应的条件转移指令

    ;条件转移指令  
    
    cmp ax,bx
    
    je  标号  ;jump euqal,(ax)=(bx),zf=1
    jne 标号  ;jump not euqal,(ax)!=(bx),zf=0
    jb  标号  ;jump blow,(ax)<(bx),cf=1
    jnb 标号  ;jump not blow,(ax)>=(bx),cf=0
    ja  标号  ;jump above,(ax)>(bx),zf=0&&cf=0
    jna 标号  ;jump not above,(ax)<=(bx),zf=1或cf=1

    DF

    控制si、di的递增或递减,若df=0则inc si,inc di反之dec si,dec di,std指令设置df=1,cld指令设置df=0.

    movsb

    串传送指令,执行此指令时CPU做如下操作:((es)16+di)=((ds)16+si),根据df的值增加或减少si与di.

    movsb一般与rep联合使用,rep movsb相当于s:movsb loop s.

    练习题

     1 ;小写字母转换为大写
     2 assume cs:codesg,ds:data
     3 
     4 data segment
     5     db 'welcome To the woRld of python!',0
     6 data ends
     7 
     8 codesg segment
     9 
    10     start:  mov ax,data
    11             mov ds,ax
    12             mov si,0
    13             call exchange
    14 
    15             mov ax,4c00h
    16             int 21h 
    17 
    18 exchange:   push si
    19             push ax
    20         s:  mov al,ds:[si]
    21             cmp al,0    ;0字符串结束
    22             je r
    23             cmp al,'a'
    24             jb s        ;小于a不处理
    25             cmp al,'z'
    26             ja s        ;大于z不处理
    27             add al,'A'-'a'
    28             mov ds:[si],al
    29             jmp short s
    30 
    31         r:  pop ax
    32             pop si
    33             ret     
    34     
    35 codesg ends
    36 
    37 end start
  • 相关阅读:
    「日常报错」Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
    LeetCode1026. 节点与其祖先之间的最大差值
    Erlang TCP 实例
    「笔记」Systemd 的基础
    折腾日记「乱七八糟的过程」
    LeetCode15.三数之和
    Sql Paging
    行变列
    SQL JOINS
    DBML存储过程返回值
  • 原文地址:https://www.cnblogs.com/michaelle/p/4023324.html
Copyright © 2011-2022 走看看