汇编语⾔学习笔记--位运算(应该貌似简单点了吧,差点⾃⼰就信了,(:{))基本
1.逻辑运算
能学到汇编的同志们,对于逻辑应该不⽤详细介绍吧,所以就直接上图了。
同理,在汇编语⾔中,也是通过这四个指令实现:
and ⽬的操作数,源操作数
or ⽬的操作数,源操作数
xor ⽬的操作数,源操作数
nor ⽬的操作数
注意:
not指令不影响任何标志位,但是其他三条指令会影响:CF、OF、PF、SF、ZF和AF等标志位!
2.⽤途
在逻辑指令中⽤来改变位值得值通常称为掩码。
and:对⽬的地址中的内容选定的位清零。原理: 任意⼀位值和1进⾏与运算,仍是原值;与0进⾏运算,结果必是0
or:对选定位置值赋值为1,原理同上
实现⾼级语⾔的布尔运算
and flags,11011101b;flag5=false,flag1=false
or flags,00001100b;flag3=true,flag2=true
汇编语言大小写字母转换
执⾏⼀些算数运算,
1.
mov edx,0
mov ebx,32
div ebx
2.
mov edx,eax
and edx,0000001fh
两种都是求模32并且将结果放在EDX中,但是第⼆种却更加简单,效率更⾼!(并且EAX没有商)
原理:
1. 将edx看作⼆进制
2. 因为⽐32(2的5次⽅)⾼的位数都可以被约分,所以只⽤看后5位的数值,5之前的数都可以⽤上⾯的⽅法进⾏屏蔽(0000001F)
3. 剩下的5位就是结果(使⽤1F进⾏与运算)
处理ASCII码字母的⼤⼩写
如下,可以发现"A"和"a"的ASCII码值⼆进制形式只有⼀位不同,因此完全可以使⽤按位取反,从⽽实现⼤⼩写的转换。
A的ASCII码为 0101 0011(⼆进制形式) 41h(16进制)  65d(10进制)
a的ASCII码为 0111 0011(⼆进制形式) 61h(16进制)  97d(10进制)
xor eax 0010 0000b;改变⼤⼩写
;以下两个完全对称,可能这就是⼆进制的魅⼒吧
or eax 0010 0000b;变为⼩写
and eax 1101 1111b;变为⼤写
test
1. test
test除了不改变⽬的操作数之外,它的功能与and指令相同。也就是说,指令test唯⼀的任务是设置标志位(cmp的指令实质上也相当于设置标志位的sub指令,但是cmp指令不改变⽬的操作数)。简单来说,就是,test只是检测对⽐⽽已,但是不影响原来的数值,只修改标志位。所以拿来和cmp进⾏⽐较。
应⽤
检查特定位的值,并且结合 j- 系列的语句实现跳转
检查13位
test dx,2000h;检测第⼗三位是0还是1,从⽽实现跳转
jz temp
获得寄存器中的值的信息
test cx,cx
任意位和⾃⼰执⾏and(test)操作的结果都是本⾝,但是通过这样可以修改标志位。
移位和循环移位
简单来说,就是将⼆进制向左移动或者向右移动。使⽤的命令是**s-**系列。
左移右移
逻辑移位shl shr
算术移位sal sar
s- ⽬的地址,count
count的三种情况
1.
s- ⽬的地址,1;移动⼀位
2.
s- ⽬的地址,8位⽴即数;⼀个字节的⽴即数,⼀半都会00011111与这个操作数作掩码,也就是说,在移位前对他进⾏模32运算,这是因为对⼀个不超过⼀个双字节长的操作数来说,做超过32位的移位操作是没有意义的。
3.
s- ⽬的地址,cl
逻辑移位和算数移位
左移
算数左移和逻辑左移都是⼀样的。当执⾏左移时,⽬的操作数的每⼀位都向左移动,最右边的空缺补0。移出的左边位被丢失,除了最后移除的⼀位,它被保存在进位标志位CF中。然后根据⽬的地址中最后的结果,来设置符号位。
右移