5.2.6 处理器选择伪指令
略
5.3 宏指令语句
5.3.1 宏处理伪指令
1.宏定义伪指令(MACRO/ENDM)
宏指令名 MACRO[NEAR/FAR] . .(宏定义体) . 过程名 ENDM
macro.asm
DATA Segment A DB 45H B DB 45H DATA ends CODE Segment Assume cs:CODE,ds:DATA start: mov ax,DATA mov ds,ax DADD MACRO OPR1,OPR2 MOV AL,OPR1 ADD AL,OPR2 DAA MOV OPR1,AL ENDM DADD A,B MOV AL,A MOV AH,4CH INT 21H CODE ends end start
2.声明宏体内局部标号的伪指令(LOCAL)
一位16进制数,转为ASCII码
local.asm
DATA Segment N DB 9H ;57=39h A DB 0AH ;65=41h DATA ends CODE Segment Assume cs:CODE,ds:DATA start: mov ax,DATA mov ds,ax HEXTOASC MACRO REG LOCAL NUM CMP REG,0AH JC NUM ADD REG,07H NUM: ADD REG,30H ENDM HEXTOASC N MOV AL,N HEXTOASC A MOV AH,A MOV AH,4CH INT 21H CODE ends end start
5.3.2 宏指令与子程序的区别
宏指令是用一条指令来代替一段程序以简化源程序的设计,子程序(过程)也有类似的功能。宏指令与子程序的区别主要表现在以下几方面:
(1)宏指令由宏汇编程序MASM在汇编过程中进行处理,在每个宏调用处,将相应的宏体插入;而子程序调用指令CALL则是CPU指令,执行CALL指令时,CPU使程序的控制转移到子程序的入口地址。
(2)宏指令简化了源程序,但不能简化目标程序。汇编以后,在宏定义处不产生机器代码,但在每个宏调用处,通过宏扩展,宏体中指令的机器代码被插入到宏调用处,因此不节省内存单元; 对于子程序来说 ,在目标程序中定义子程序的地方将产生相应的机器代码,但每次 调用时,只需用CALL指令,不再重复出现子程的机器代码,一般来说可以节省内存单元。
(3)从执行时间来看, 调用子程序和从子程序返回需要保护断点、恢复断点等等,都将额外占用CPU的时间,而宏指令则不需要,因此相对来说,它的执行速度较快。
5.4 常用系统功能调用和BIOS中断调用
5.4.1 系统功能调用
4. 10号功能调用
调用格式
MOV DX ;数据区的首偏移地址 MOV AH,10 INT 21H
该功能调用将从键盘接收字符串到内存数据区。要求事先定义一个数据区,数据区内一个单元指出数据区能容纳的字符个数,不能为零,第二个单元保留,以用作填写实际输入的字符个数。从第三个单元开始存放从键盘上接收的字符串,实际输入的字符数。若少于定义的字符数,数据区内剩余单元填零,若多于定义的字节数,则后来输入的字符丢掉,且响铃。调用时,要求DS:DX指向数据区首地址,例如
10.asm
DATA SEGMENT BUF DB 50 ;定义包括回车将在内允许键入的字符最大个数 DB?:保留,调用结束后填入实际输入的字符个数(不包括回车符) DB 50 DUP(?),存储包括回车符在内的键入字符的ASCII码值 DATA ENDS CODE SEGMENT MOV DX, OFFSET BUF MOV AH,10 INT 21H CODE ENDS
5.4.2 常用系统功能调用应用举例
略
5.4.3 BIOS中断调用
略
5.5 汇编语言程序设计的基本方法
5.5.1 顺序程序设计
5.5.2 分支程序设计
- 分段函数
- 统计个数
5.5.3 循环程序设计
- 最大值
- 求和
(1)用计数控制循环。这种方法直观、方便,易于程序设计。只要在编制程序时,循环次数已知,就可以使用这种方法设计循环程序。
【例5.12】从xx单元开始的30个连续单元中存放有30个无符号数,从中找出最大者送入yy单元中。根据题意,我们把第一个数先送入AL寄存器,将AL中的数与后面的29个数逐个进行比较,如果AL中的数较小,则两数交换位置;如果AL中的数大于等于相比较的数,则两数不交换位置。在比较过程中,AL中始终保持较大的数,比较29次,则最大者必在AL中,最后把AL中的数(最大者)送入yy单元。
这个问题的特点是循环比较的次数是已知的,因此可以用计数器控制循环,程序的流程图如图5.11所示。
DATA SEGMENT xx DB 1,2,3,4,5,9,8,7,6,0 ;30个用10个代替 yy DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AL,xx MOV SI, OFFSET xx MOV CX,10 LOOP1: INC SI CMP AL,[SI] JAE LOOP2 XCHG AL,[SI] LOOP2: DEC CX JNZ LOOP1 MOV yy, AL mov ah,4ch int 21h CODE ENDS END START
(2)用条件控制循环。有些情况无法确定循环次数,但可用某种条件来确定是否结束循环。这时,编制程序主要是寻找控制条件以及对控制条件的检测。
例5.13从自然数1开始累加,直到累加和大于1000为止,统计被累加的自然数的个数,并把统计的个数送入n,把累加和送入sum单元,根据题意,被累加的自然数的个数事先是未知的,也就是说,循环的次数是未知的,因此不能用计数器方法控制循环。但题目中给定一个重要条件,即累加和大于1000则停止累
加,因此,可以根据这一条件控制循环。我们用CX寄存器统计自然数的个数,用AX寄存器存放累加和,用BX寄存器存放每次取得的自然数。程序的流程图如图5.12所示。
程序如下;
DATAS SEGMENT n DW ? sum DW ? DATAS ENDS CODES SEGMENT ASSUME CS: CODES,DS:DATAS START: MOV AX,DATAS MOV DS,AX MOV AX,0 MOV BX,0 MOV CX,0 LOOPT: INC BX ADD AX,BX INC CX CMP AX,10 ;1000用10代替 JBE LOOPT MOV n,CX MOV sum,AX MOV AH,4CH INT 21H CODES ENDS END START
5.5.4 子程序设计
5.6 发挥80386及其后继机型的优势
略
最后
打赏通道