汇编语言-010(循环移位ROL,ROR 、进位循环进位RCL,RCR 、有符号数溢出 、双精度移位SHLD,SHRD、SHL和ADD计算 、位运算应用)

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表示是131内的日期,位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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值