每种汇编语言都有进行操作数移位的指令,移位和循环移位指令在控制硬件设备,加密数据,以及实现高速图形运算时特别有用,移位指令也是汇编语言中最具特征的指令集,移位(Shifting)的含义是在操作数内向左或向右移动数据位,Intel处理器提供了多种移位指令,具体如下表所示:

指令集 含义 指令集 含义
SHL 逻辑左移(无符号数) SHR 逻辑右移(无符号数)
SAL 算数左移(有符号数) SAR 算数右移(有符号数)
ROL 循环左移(无符号数) ROR 循环右移(无符号数)
RCL 循环左移(带进位的) RCR 循环右移(带进位的)
SHLD 双精度左移(无符号) SHRD 双精度右移(无符号)

SHL指令: 对目标操作数执行逻辑左移(针对无符号数)操作,其左移后最低位0填充,而移动出去的最高位则会送入CF(进位标志)中,原来的进位标志位中的值将被覆盖.

Intel处理器中定义,执行移位的源操作数的范围必须在0-255之间,在任何处理器上都可以使用CL寄存器存放移位位数,例如在下面的指令中,AL寄存器被左移一位,最高位被复制到了进位标志中,最低位被清零:

01251006 | B3 8F                | mov al,10001111b                            | AL = 10001111b
01251008 | D0E3                 | shl al,1                                    | CF = 1,AL = 00011110b01251006 | B0 01                | mov al,10000000b                            | AL = 10000000b
01251008 | C0E0 02              | shl al,2                                    | CF = 0,AL = 00000000b01251006 | B0 01                | mov al,10000000b                            | AL = 10000000b
01251008 | C0E0 01              | shl al,1                                    | CF = 1,AL = 00000000b01251006 | B0 01                | mov al,10100000b                            | AL = 10100000b
01251008 | C0E0 03              | shl al,2                                    | CF = 0,AL = 10000000b

另外使用SHL指令还可以进行2的次幂的高速乘法运算,任何操作数左移动N位,就相当于乘以2的N次方,如下例子:

01311002 | B0 05                | mov al,5                                    | AL 左移动1位
01311004 | D0E0                 | shl al,1                                    | al*2=1001311007 | B0 05                | mov al,5                                    | AL左移2位
01311009 | C0E0 02              | shl al,2                                    | al*4=2001311007 | B0 05                | mov al,5                                    | AL左移3位
01311009 | C0E0 03              | shl al,3                                    | al*8=40

SHR指令: 对目标操作数执行逻辑右移(针对无符号数)操作,移出的数据位用0代替,最低位被复制到CF进位标志中,原来的进位标志位丢失.

0131100D | B0 01                | mov al,10001111b                            | AL = 10001111b
0131100F | D0E8                 | shr al,1                                    | CF = 1,AL = 01000111b0131100D | B0 01                | mov al,10001111b                            | AL = 10001111b
0131100F | D0E8                 | shr al,2                                    | CF = 1,AL = 00100011b

另外任何无符号操作数逻辑右移N位,就相当于该操作数除以2的N次方,如下例子:

01311012 | B2 20                | mov dl,20                                   | DL 右移1位
01311014 | D0EA                 | shr dl,1                                    | dl/2 = 1001311012 | B2 20                | mov dl,20                                   | DL 右移2位
01311014 | D0EA                 | shr dl,2                                    | dl/4 = 5

MUL和IMUL指令分别进行有符号整数和无符号整数的乘法操作,MUL(无符号乘法)指令有三种格式.

8位乘法: 计算AL寄存器BL寄存器相乘,积数默认放在AX寄存器中,进位标志CF清零,因为AH高位等于零.

00111002  | B0 05                    | mov al,5                                 | al = 5
00111004  | B3 10                    | mov bl,10                                | bl = 10
00111006  | F6E3                     | mul bl                                   | AX=50,CF=0

16位乘法: 将16操作数2000h和100h相乘,乘积高位在DX中,低位在AX中.CF=1因为乘机高半部分DX=0

0008100F  | 66:B8 0020               | mov ax,2000                              | ax=2000
00081013  | 66:BB 0001               | mov bx,100                               | bx=100
00081017  | 66:F7E3                  | mul bx                                   | ax*bx

32位乘法: 将32操作数12345h和1000h相乘,得到64位乘积,其高位在EDX中,低位在EAX中.

0008101B  | B8 45230100              | mov eax,12345                            |
00081020  | BB 00100000              | mov ebx,1000                             |
00081025  | F7E3                     | mul ebx                                  |

IF-ENDIF 伪指令: 32位汇编中支持决策伪指令,通过使用该伪指令可以节约判断跳转的时间,提高开发效率.

.codemain PROCmov eax,100mov ebx,200.IF (eax == ebx) && (ebx == ebx)xor eax,eaxxor ebx,ebx.ELSEIF (eax >= 100) || (ebx == ebx)add eax,100add ebx,100.ENDIFmain ENDP
END main

WHILE-ENDW(伪指令):

.dataCount DWORD 10SumNum DWORD 0.codemain PROCxor eax,eax.WHILE (eax < Count)add SumNum,1inc eax.ENDWmain ENDP
END main

REPEAT-UNTIL(伪指令): 以下代码利用循环伪指令,完成了1-10相加.

.dataCount DWORD 10SumNum DWORD 0
.codemain PROCxor eax,eax.REPEATinc eaxadd SumNum,1.UNTIL (eax >= Count)main ENDP
END main

BREAK(伪指令): 以下是个死循环,当eax寄存器的值等于5时,则执行.break结束程序的运行.

.codemain PROCmov eax,10.while (1)dec eax.break .if(eax == 5).endwretmain ENDP
END main

CONTINUE(伪指令): 当EAX的值小于等于5时执行continue,否则执行inc ebx,总循环数为10.

.codemain PROCmov eax,0mov ebx,0.repeatinc eax.continue .if(eax <= 5)inc ebx.until (eax >= 10)retmain ENDP
END main

FOR 字符替换(伪指令): 该伪指令并不是循环,而是分别将指定的指令批量的替换到程序中.

.codemain PROCfor num,<1,2,3>xor eax,eaxadd eax,DWORD PTR [num]endmretmain ENDP
END main

FORC字串替换(伪指令): 该伪指令并不是循环,而是分别将指定的字串批量的替换到程序中.

.codemain PROCforc code,<@#$%^&*()<>>BYTE "&code"endmretmain ENDP
END main

Win32汇编:算术与伪指令相关推荐

  1. win32汇编·指令

    win32汇编·指令 常用伪指令 数字常量 字符串常量 预留空间 复制重复 符号定义伪指令 等号伪指令 操作符伪指令 算术运算符 逻辑操作符 关系操作符 框架定义 样例 函数声明语句 include ...

  2. win32 汇编基础概念整理

    一.关于寄存器 寄存器有EAX,EBX,ECX,EDX,EDI,ESI,ESP,EBP等,似乎IP也是寄存器,但只有在CALL/RET在中会默认使用它,其它情况很少使用到,暂时可以不用理会. EAX是 ...

  3. Win32汇编_基础

    Win32汇编_基础 包含全部段的源程序结构: .386 .model flat, stdcall Option casemap:none ;<一些include语句> .stack [堆 ...

  4. Win32汇编基本编程框架

    Win32汇编编程框架如下: .386 .model flat,stdcall option casemap:none <一些include语句> .stack [堆栈段的大小] .dat ...

  5. Win32 汇编环境和入门程序图解

    一 安装 在安装的最后,执行VBS脚本,在桌面建立快捷方式:执行快捷方式,会调入Win32汇编的编辑器qeditor.exe,进入到开发环境 二 构建Hello World程序 ;.386是伪指令 告 ...

  6. C指针原理(23)-win32汇编及.NET调试

    2018-12-28 20:36:07 在WINDOWS系统能用到汇编的机会不多,基本都可以用C或C++代劳,更何况现在MICROSOFT的Visual Studio 系列工具非常强大,WINDOWS ...

  7. win32汇编基础概念

    一.关于寄存器 寄存器有EAX,EBX,ECX,EDX,EDI,ESI,ESP,EBP等,似乎IP也是寄存器,但只有在CALL/RET在中会默认使用它,其它情况很少使用到,暂时可以不用理会. EAX是 ...

  8. ARM汇编指令(ARM寻址方式、汇编指令、伪指令

    1.寻址方式 所谓寻址方式就是:处理器根据指令中给出的地址信息来寻找物理地址的方法. 1)立即寻址 立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就是在指令中给出的. 只要取出指令也就是取 ...

  9. Win32汇编学习笔记之基础篇

    基础篇 第一章 背景知识 1.1 Win32的软硬件平台 1.1.1    80x86系列处理器简史 Win32可以在多种硬件平台上运行,但使用最广泛的硬件平台是基于Intel公司80x86系列处理器 ...

  10. Win10系统VS2022开发环境中(X86)Win32汇编(MASM32)环境配置和一些示例源码及解释

    抱歉,还是只能用米国的软件以及技术以及等等等等......,所以各位勿怪. 如果配置完成,在vs2022调试环境下正确编译运行后,可以看到如下画面: 在VS022中开发学习汇编必然很方便. 这里可以下 ...

最新文章

  1. 库函数和系统调用的区别和联系
  2. 从源码分析DEARGUI之add_radio_button
  3. RhinoMock学习-绑定回调
  4. Python读取PDF内容
  5. 前端基础:web语义化
  6. 区块链演进及跨域安全解决方案
  7. 如何在android studio中设置sdk path?
  8. 运行APP脚本的步骤
  9. adobe audition cs6 能打开mpcm文件吗?_单根32G内存靠谱吗?阿斯加特 W2 32G DDR4 2666内存测试...
  10. 二叉搜索树bst_二进制搜索树(BST)–搜索插入和删除
  11. 搭建完美的数学计算环境: iTeXmacs+maxima
  12. 韩国历史最悠久的银行推出全国区块链贷款平台
  13. Python 数据分析练习1:美国人口数据分析
  14. 【转】Ouroboros:一个可证明安全的PoS区块链协议 (共识介绍)
  15. vue的三种传值方式:父传子,子传父,子传子
  16. 服务器与pycharm的连接
  17. 使用硬盘空间少的linux系统,linux磁盘空间不足的解决办法
  18. java接口可以写方法体吗_JDK1.8接口中可以写方法体
  19. HTML中基本元素基本设置(例如:字体颜色、大小、背景颜色)。
  20. 使用scale缩放字体

热门文章

  1. Oracle学习笔记(七)——分组统计查询
  2. 毕业设计-基于深度学习的古文字识别系统
  3. ClickOnce测试发布简述
  4. activiti工作流学习(四)
  5. python web开发框架比较
  6. python 的数组排序问题
  7. React前端ui框架收集
  8. git如何查看本地分支及对应的远程分支
  9. 聆听东方的罗密欧与朱丽叶
  10. mysql中的mvcc机制