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