汇编基础:顺序、分支与循环程序设计
2017-06-10
一个算法用程序设计语言的语句有序地组合在一起加以描述,其组合方式称为程序的控制结构或简称为程序结构。程序的基本结构形式有顺序结构、分支结构和循环结构。
一、顺序结构
顺序结构是最简单的,也是最基本的程序结构形式,这种结构形式的程序的最大特点就是程序运行时从开始到结尾一直是按照编写指令的顺序执行,且每条指令仅执行一次,具有顺序结构的程序或者程序段,成为顺序程序。
我们拿一个简单的程序来说明汇编的顺序程序设计。
例:设两个字存储变量X和Y, 编程实现这两个变量的交换。
分析:由于存储单元之间不能够直接进行数据交换,所以利用通用寄存器AX来作为交换的中介。我在这里给出一个代码范例:
DATA SEGMENT
X DW 1032H
Y DW 2043H
DATA ENDS
STACK1 SEGMENT PARA STACK
DW 20H DUP (0)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK1
BEGIN: MOV AX, DATA
MOV DS, AX
MOV AX, X
XCHG AX, Y
MOV X, AX
MOV AH, 4CH
INT 21H
CODE ENDS
END
代码分析:前面一部分是对数据以及堆栈的定义,这里我就不再多说了,我们从BEGIN开始,因为对于MOV来说,不能够直接将DATA作为源操作数,DS作为目的操作数,所以要通过一个通用寄存器来实现两者之间的赋值,MOV AX, X意为将X的值先保存在AX中,而后执行XCHG AX, Y将AX与Y的值进行交换,此时Y里面存储的便是X的值,AX中存储的Y的值。紧接着MOV X, AX再将AX中存储的Y的值赋予X,即实现X与Y值得交换。
二、分支程序设计
实现分支程序需要有相应的转移指令的支持,而转移指令又分为无条件转移指令与有条件转移指令两类,在有条件转移指令中,不同的条件往往是通过标志寄存器中条件标志的不同状态反映的。因而,分支程序设计中一个至关重要的问题是如何根据标志寄存器中标志位的不同状态,配合使用合适的转移指令实现程序的转移。关于转移指令请看我的另一篇文(http://yiluohuanghun.blog.51cto.com/3407300/940123)。
还是拿例子来说吧:X为存储单元中的有符号字数据,编写程序实现计算其绝对值,并保存到原处。
分析:当X>=0时,X的绝对值就是它本身,否则利用求负指令将X变号,并放回要原处,下面我给出了一个程序,大家可以参考下:
DATA SEGMENT
X DW 0F874H
DATA ENDS
STACK1 SEGMENT PARA STACK
DW 20H DUP (0)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK1
BEGIN: MOV AX, DATA
MOV DS, AX
MOV AX, X
TEST AX, AX
JNS DONE
NEG X ;负指令NEG对X取反
DONE: MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN
程序分析:TESTAX, AX;此处目的是为了重置标志寄存器各位的值,以便于下一条指令JNS使用标志寄存器
三、循环程序设计
在进行循环程序设计之前同分支程序设计一样,都要先知道一个基本控制指令,对于循环控制指令有如下4大类:
1、LOOPTARGET
执行的操作:先将CX<-(CX)-1,如果(CX)不等于0,则将IP指向TARGET的偏移量
2、LOOPZ/LOOPETARGET
执行操作:先将CX<-(CX)-1,如果(CX)不等于0并且ZF=1,则将IP指向TARGET的偏移量
3、LOOPNZ/LOOPNE TARGET
执行操作:先将CX<-(CX)-1,如果(CX)不等于0并且ZF不等于1,则将IP指向TARGET的偏移
4、JCXZTARGET
执行操作:测试(CX)是否0,但不对CX寄存器进行修改,如果(CX)=0,那么IP指向TARGET的偏移量
下面还是以实例来说明问题:数据段的ARY数组中存放有10个无符号数,试找出其中最大者送入MAX单元。
分析:首先将数组中的第一个数取出放入AL,然后依次与数组中的其他元素进行比较,将较大者放入AL中,遍历数组后,AL中存放的就是最大的数。具体实现过成功如下:
DATA SEGMENT
ARY DB 17, 5, 40, 0, 67, 12, 34, 78, 32, 10
MAX DB ?
DATA ENDS
STACK1 SEGMENT PARA STACK
DW 20H DUP (0)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE, SS:STACK1, DS:DATA
BEGIN: MOV AX, DATA
MOV DS, AX
MOV SI, OFFSET ARY ;SI指向ARY的第一个元素
MOV CX, 9 ;CX作循环次数计数
MOV AL, [SI] ;取第一个元素到AL
LOP: INC SI ;SI指向后一个元素
CMP AL, [SI] ;比较两个数
JAE BIGER ;前一个元素大于后一个元素时转移
MOV AL, [SI] ;取较大数到AL
BIGER: LOOP LOP ;(CX)不等于0 则转移
MOV MAX, AL
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN
以上就介绍着三种程序设计方式。