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

 

转载于:https://www.cnblogs.com/michaelle/p/4023324.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值