顺序程序结构
按照指令前后顺序执行每条指令,形成顺序程序结构。
举例:移位实现乘法
移位是以位为单位将数据向左或向右的移动,移位操作是最基本的数据处理方法。
- 左移一位相当于数值乘以2;
- 右移一位相当于数值除以2(余数在CF中,逻辑右移一位是无符号整数除以2;算术右移一位是有符号数除以2)。
- 对数据加减、配合移位操作可以实现乘除法运算。
- 两个整数相乘可以用移位配合加减运算实现,可以提高乘法操作的速度,实现代码优化。
举例:64位数据移位程序
IA-32 支持8、16和32位数据的各种移位操作,对于64位数据需要分成高32位、低32位分别移位。
高低32位中间的
D
32
D_{32}
D32和
D
31
D_{31}
D31位利用CF衔接。不仅要使用移位指令SHL、SHR和SAL、SAR,还要使用带进位的循环移位指令RCL或RCR。
如64位数据的逻辑右移:使用SHR指令将高32位右移一位,最高位补0,最低位送入CF;再使用RCR指令将低32位循环右移,将CF中的数据放到低32位的最高位,再将低32位的最低位送入CF。
分支程序结构
分支程序结构由条件产生和条件判断两个部分组成。首先,利用比较指令CMP、测试指令TEST、加减运算或逻辑运算等影响状态标志的指令形成条件;然后,利用条件转移指令判断由标志表达的条件并根据状态标志控制程序转移到不同的程序段。
单分支结构
只有一个分支的程序,类似if-then语句。
当条件满足时,发生转移,跳过分支体;
当条件不满足时,顺序向下执行分支体。
举例:数据范围的通用判断方法
; e.g. 对范围内数据进行处理
.code
cmp eax, min ; 小于最小值,结束
jb/jl done
cmp eax, max ;大于最大值,结束
ja/jg done
... ; 最大值最小值范围之间顺序执行分支体
done:
双分支结构
有两个分支,相当于if-then-else语句。
条件为真,转移,执行分支体2;
条件为假,顺序执行分支体1。在顺序执行的分支体(1)最后有一定要有jmp指令跳过分支体2。
; e.g. 显示数据最高位(非 0 即 1 )程序
; e.g. jc
.data
dvar dword 0bd980612H
.code
mov ebx, dvar ; 数据来自变量 dvar
shl ebx, 1 ; ebx 最高位移入 cf 标志
jc one ; CF = 1 ,即最高位为 1 ,转移
mov al, '0' ; CF = 0 ,即最高位为 0 ,al = 0
jmp two ; 跳过另一个分支(one)
one: mov al, '1' ; al = 1
two: call dispc
循环程序结构
循环程序结构通常由三个部分组成:① 循环初始;② 循环体;③ 循环控制。
- 循环初始:为开始循环准备必要的条件,如设置循环次数、循环体需要的初值等;
- 循环体:重复执行的程序代码,包括对\textcolor{red}{循环条件的修改}等;
- 循环控制:判断循环条件(计数控制循环、条件控制循环)是否成立,决定是否继续循环。
计数控制循环
计数控制循环通过次数控制循环。
- 计数可以减量进行—减到0结束(loop),类似高级语言的for语言。
- 计数可以增量进行—达到规定值结束,类似高级语言的for语言。
- 常见“先循环,后判断”循环结构(先执行循环体,判断循环条件是否满足,满足则jmp回循环体之前),对应高级语言的do语句。
条件控制循环
条件控制循环根据条件决定是否进行循环。
- 使用比较、测试等指令设置状态标志、产生条件。
- 使用条件转移指令实现循环控制。
- 常需要使用无条件转移指令配合实现循环,多见是“先判断、后循环”循环结构(不满足执行循环体,然后jmp回循环条件判断之前),对应高级语言的while语句。