汇编学习笔记(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

 

你可能感兴趣的:(学习笔记)