1 :循环移位ROL,ROR,带进位循环进位RCL,RCR
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.code
main PROC
;循环左移
mov al,40h ;AL = 010000000b
rol al,1 ;AL = 100000000b ,CF = 0
rol al,1 ;AL = 000000001b ,CF = 1
rol al,1 ;AL = 000000010b ,CF = 0
mov al,00100000b
rol al,3 ;CF = 1,AL = 00000001b
;位组交换,向任意方向循环4位就可以高低字节交换
mov al,26h
rol al,4 ;AL = 62h
;循环右移
mov al,01h ;AL = 00000001b
ror al,1 ;AL = 10000000b ,CF = 1
ror al,1 ;AL = 01000000b ,CF = 0
mov al,00000100b
ror al,3 ;AL = 10000000b,CF = 1
;带进位循环左移
clc ;清除进位标志位 CF = 0
mov bl,88h ;CF = 0, BL = 10001000b
rcl bl,1 ;CF = 1, BL = 00010000b
rcl bl,1 ;CF = 0, BL = 00100001b
;从进位标志位恢复位
shr bl,1 ;将最低位移入进位标志位
rcl bl,1 ;恢复该数原值
;带进位循环右移
stc ;将进位标志位置为1 CF = 1
mov ah,10h ;AH = 00010000b ,CF =1
rcr ah,1 ;AH = 10001000b ,CF =0
INVOKE ExitProcess,0
main ENDP
END main
2 :有符号数溢出
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.code
main PROC
;如果有符号数循环移动一位生成的结果超过了目的操作数的有符号范围
;溢出就为1,换句话说:即该数的符号位取反了
mov al,+127 ;AL = 01111111b
rol al,1 ;OF = 1,AL = 11111110b
mov al,-128 ;10000000B
shr al,1 ;OF = 1,AL = 01000000b
;如果循环移动次数大于1,则溢出标志无定义
mov al,-128 ;10000000B
shr al,1 ;OF = 0,AL = 00100000b
INVOKE ExitProcess,0
main ENDP
END main
3:双精度移位SHLD,SHRD
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
wval WORD 9BA6h
.code
main PROC
;双精度左移,将AX的高4位复制到wval的低4位
mov ax,0AC36h
shld wval,ax,4 ;wval = BA6Ah ,ax = AX36h
;双精度右移,将dx的低4位复制到ax的高4位
mov ax,234Bh
mov dx,7654h
shrd ax,dx,4 ;ax = 4234
INVOKE ExitProcess,0
main ENDP
END main
4 : 双精度移位例子,将一个双字数组右移4位
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
array DWORD 648B2165h,8C943A29h,6DFA4B86h,91F76C04h,8BAF9857h
.code
main PROC
mov bl,4 ;移动次数
mov esi,OFFSET array ;数组偏移量
mov ecx,(LENGTHOF array) -1 ;数组元素个数
L1:
push ecx
mov eax,[esi + TYPE DWORD]
mov cl,bl ;移动次数
shrd [esi],eax,cl ;EAX移入[ESI]的高位
add esi,TYPE DWORD ;指向下一对双字
pop ecx
loop L1
shr DWORD PTR[esi],4 ;最后一个双字进行移位
INVOKE ExitProcess,0
main ENDP
END main
5 :不用使用SHRD指令将AX的最低移入BX的最高位,再使用SHRD指令移入
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.code
main PROC
;不使用SHRD指令,将AX的最低位移入BX的最高位
mov ax,1111111111111111b
mov bx,0011111111111111b
mov si,ax
shr si,1
rcr bx,1
;使用SHRD指令,将AX的最低位移入BX的最高位
mov ax,1111111111111111b
mov bx,0011111111111111b
shrd bx,ax,1
INVOKE ExitProcess,0
main ENDP
END main
6:利用循环将EAX的每一位移入进位标志位,计算进位标志位置的1次数,计算32位数奇偶性
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.code
main PROC
mov ebx,0
mov ecx,32
mov eax,89ABCDEFh
L1:
ror eax,1
jnc L2
inc ebx
L2:
loop L1
and ebx,1
jz L3
mov edx,0 ;奇数
jmp quit
L3:
mov edx,1 ;偶数
quit:
INVOKE ExitProcess,0
main ENDP
END main
7:使用shr与rcr 将 字节数组右移一位
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
ArraySize = 3
array BYTE ArraySize DUP(99h) ;每半个字节都是1001
.code
main PROC
mov esi,0
shr array[esi+2],1 ;高字节
rcr array[esi+1],1 ;中间字节,包括进位标志位
rcr array[esi],1 ;低字节,包含进位标志位
INVOKE ExitProcess,0
main ENDP
END main
8:将无符号整数乘法,转换成使用SHL和ADD计算
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.code
main PROC
;123 * 36 可以使用以下位运算替换
;36 = 00100100
;乘数36的位2和位5都是1,所以下面123左移5位和2位相加
mov eax,123
mov ebx,eax
shl eax,5 ;
shl ebx,2
add eax,ebx ;乘积相加
INVOKE ExitProcess,0
main ENDP
END main
9:将32位二进制整数转换为ASCII码的二进制形式
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.code
main PROC
INVOKE ExitProcess,0
main ENDP
;将32位二进制整数转换为ASCII码的二进制形式
;接收:EAX = 二进制整数,ESI 为缓冲区指针
;返回包含ASCII码二进制数字的缓冲区
BinToAsc PROC
push ecx
push esi
mov ecx,32 ;EAX中的位数
L1:
shl eax,1 ;最高位移入进位标志位
mov BYTE PTR[esi],'0' ;选择0作为默认数字
jnc L2 ;如果进位标志位为0,就跳到L2
mov BYTE PTR[esi],'1' ;否则将1送往缓冲区
L2:
inc esi
loop L1
pop esi
pop ecx
ret
BinToAsc ENDP
END main
10:位运算应用,在实地址模式下取文件日期
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
day BYTE ?
month BYTE ?
year WORD ?
.code
main PROC
;在实地址模式下,MS_DOS函数57h 用DX返回文件的日期戳,(该文件最后被修改的日期)
;位0到位4表示是1到31内的日期,位5到位8表示是月份,位9到位15表示年份
mov dx,0010011001101010b
;取日期
mov al,dl ;复制DL
and al,00011111b;清除位5到位7
mov day,al
;取月份
mov ax,dx
shr ax,5 ;右移5位
and al,00001111b ;清除位4到位7
mov month,al
;取年份
mov al,dh
shr al,1
mov ah,0
add ax,1980 ;年份以1980为基点
mov year,ax
INVOKE ExitProcess,0
main ENDP
END main