汇编语言第六章
汇编语言第六章
6.3
操作.
串操作指令
包括串传送、存取、比较、扫描等
利用串操作指令可以直接处理两个存储
器操作数,方便地处理字符串或数据块。
串指令的特点
(1).指令格式
串指令可以显式地带有操作数,也可以使 用隐含格式。例如串传送指令MOVS,可以有以 下几种格式:
显式:MOVS DST,SRC
隐式:MOVSB ;字节传送
第6章 循环程序设计
6.1 循环结构程序设计
一、循环结构程序概述
在程序中,凡能有规则重复执行的程序段 称作循环。
包含循环程序段的程序称为循环结构程序。
1、循环程序的组成
循环的初始状态:设置一些初值,如设寄存器、
计数器的初值等。
循环体:由工作部分和修改部分构成。工作部
分是循环程序具体要完成的功能,是循环的主 . 要部分,修改部分是控制循环的一些参数有规
LODSD
功能:源→累加器,即([SI]) →AL(或AX、 说明:若DF=0,则LODSB(或LODSW)使SI加1(或 2);若DF=1,则LODSB(或LODSW)使SI减1(或2)。 标志:不影响标志位。
② 自buffer1开始的10个非压缩BCD码形式存放的十进
制数转换成ASCII码,按顺序显示在屏幕上。设DS、ES 已按要求设置
作业从自然数作业从自然数1开始累加直到累加和大于500为止统计被累加的自然数的个数并把统计的个数送入单元为止统计被累加的自然数的个数并把统计的个数送入单元n中把累加和送入单元sum中
思考题: 下面的代码段完成什么功能?
MOV cx,20 LAST:MOV AL,[SI] MOV ES:[DI],AL INC SI INC DI DEC CX JNZ LAST
第六章 汇编语言程序设计
AA:
SUB MOV MOV HLT
BX,AX DI, 2800H [DI],BX
16
改: CLC CMP JC SUB MOV MOV HLT AA: SUB MOV MOV HLT BX,AX DI, 2800H [DI],BX
17
AX,BX AA AX,BX DI, 2800H [DI],AX
CMP JZ CMP JZ MOV JMP NEXT: DONE: MOV HLT AL, 'y ' ;比较AL与小写字母y NEXT ;相等,转移到NEXT AL, 'Y ' ;不是小写字母y,是大写字母Y ? NEXT AH,-1 ;相等,转移NEXT ;不是大Y ,令AH=-1 Y AH 1
DONE ;无条件转移DONE AH,0 ;是Y或Y,令AH=0
AL,BL , AL,0 , STOR AL,80H , MINUS AL, 1 , STOR AL,0FFH , BH,AL ,
;取X ;X=0,Y=X , ;X<0 < ;X>0,Y=+1 > , X<0,Y= -1 < , ;保存Y 保存
MINUS: : STOR: :
MOV MOV HLT
例4,判断是否为字母 .若AL中是字母Y(含大小写),则令AH ,判断是否为字母Y. =0,否则令AH=-1
为奇数, ;否则AX为奇数,加1 否则 为奇数 ;AX←AX÷2 ÷
12
法2:将最低位用移位指令移至进位标志,判断进位标志 :将最低位用移位指令移至进位标志, 就是偶数; 是0,AX就是偶数;否则,为奇数 , 就是偶数 否则,
MOV SHR JNC ADD E1: SHR
汇编语言第6章
外设
内存
CPU
DMA控制器
4.中断传送 在查询传送方式中,CPU与外设串行工作,外设在进行I/O操作时,CPU并未进行其它的工作而是处于长时间反复查询的等待状态。为提高CPU的效率,采用中断方式,中断的特点是CPU与外设并行工作,即CPU启动外设之后,不再等待外设工作的完成,而是执行另一个程序。输入时,当外设就绪,主动向CPU发出中断请求,让CPU为其服务,CPU接到请求后,暂时中断现行程序的运行,转去执行处理相应的中断服务程序,完成所需的数据输入,当处理结束后,CPU又返回到被中断程序的断点处继续往下执行原来中断了的程序;在输出时,当外设空闲时,向CPU发出中断请求,CPU暂停当前程序的执行,转去执行相应中断服务程序,完成所需的数据输出,然后再返回去执行原来中断了的程序。这种方式避免了CPU反复查询外设的状态而浪费时间,节省大量的CPU时间,又可以使多台外围设备与CPU并行工作。
三、I/O的传送方式
外设与CPU之间进行数据、状态和控制三种信息传送,这些信息以四种方式进行传送。 1.无条件传送 当外设的数据传送是定时的,即外设与CPU同步的情况下,CPU不需要查询外设的状态,而直接用IN或OUT指令实现CPU与指定的外设寄存器之间的信息传送。如当输入信息是开关量时,开关已设定,只要用输入指令,肯定会读入开关的状态。无条件传送是最简单的数据传送方式,它所需要的硬件和软件都是最节省的,但这种方式必须在已知并确信外设已处于准备就绪的情况下才能使用,否则就会出错。
汇编语言第六章PPT
具有对数据的锁存能力; 不具备对数据的控制能力
24
常用锁存器芯片
74LS273 8D触发器,不具备数据的控制能力
P239图
74LS373 含三态的8D触发器,具有对数据的控 制能力
25
锁存器芯片74LS374
做输出口:
Q0 D0~D7 Q0~Q7
做输入口:
D0
. . .
译码器
CP OE Q7
外设向DMA控制器发出“DMA传送请求”信 号DRQ;
DMA控制器收到请求后,向CPU发出“总线 请求”信号HOLD; CPU在完成当前总线周期后会立即发出HLDA
信号,对HOLD信号进行响应;
DMA控制器收到HLDA信号后,就开始控制总 线,并向外设发出DMA响应信号DACK
40
DMA控制方式的工作过程
复杂性
实时性 异步性
与设备无关性
3
二、I/O接口和端口
I/O接口:
将外设连接到总线上的一组逻辑电路的总称。
实现外设与主机之间的信息交换。
I/O端口:
接口中的寄存器
4
接口的功能
数据的缓冲与暂存
信号电平与类型的转换 增加信号的驱动能力 对外设进行监测、控制与管理,中断处理
8
端口与内存的统一编址
特点:
00000H 内存 地址 960KB F0000H I/O地址 64KB FFFFFH
9
优点:指令与内存指令统一 缺点:内存地址资源减少
端口的独立编址
特点:
00000H
汇编语言第六章答案
6.1 下面的程序段有错吗?若有,请指出错误。
CRAY PROCPUSH AXADD AX, BXRETENDP CRAY答:程序有错。
改正如下:CRAY PROCADD AX, BXRETCRAY ENDP ;CRAY是过程名,应放在ENDP的前面6.2 9BHF7H57H80HF0A0:00B0H先PUSH,SP-2再PUSH,SP-2POP, SP+26.2 题堆栈及SP内容的变化过程已知堆栈寄存器SS的内容是0F0A0H,堆栈指示器SP的内容是00B0H,先执行两条把8057H 和0F79BH分别入栈的PUSH指令,然后执行一条POP指令。
试画出示意图说明堆栈及SP 内容的变化过程。
答:变化过程如右图所示:6.3 分析下面的程序,画出堆栈最满时各单元的地址及内容。
;********************************************S_SEG SEGMENT AT 1000H ;定义堆栈段DW 200 DUP (?) ;200*2=190HTOS LABEL WORDS_SEG ENDS;********************************************C_SEG SEGMENT ;定义代码段ASSUME CS: C_SEG, SS: S_SEGSTART: MOV AX, S_SEG(FLAGS)(AX)T_ADDR0000(DS)1000:0184:0186:0188:018A:018C:018ESP:01866.3 题堆栈最满时各单元的地址及内容MOV SS, AXMOV SP, OFFSET TOSPUSH DSMOV AX, 0PUSH AX┇PUSH T_ADDRPUSH AXPUSHF┇POPFPOP AXPOP T_ADDRRET;-------------------------------------------------------------------------- C_SEG ENDS ;代码段结束;******************************************END START ;程序结束答:堆栈最满时各单元的地址及内容如右图所示:6.4 分析下面的程序,写出堆栈最满时各单元的地址及内容。
《汇编语言》第2版 第六单元
6.2 在代码段中使用栈
程序6.3 codesg cs:codesg 程序6.3 assumesegment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 start:mov start:mov ax,cs mov ss,ax mov sp,30h ;将设置栈顶 ;将设置栈顶SS:SP指向CS:30 将设置栈顶SS:SP指向 指向CS:30 mov bx,0 mov cx,8 s: push cs:[bx] add bx,2 loop s ;以上将代码段0~15单元中的8个字型数据依次入栈 ;以上将代码段 以上将代码段0~15单元中的 单元中的8 mov bx,0 mov cx,8 s0: pop cs:[bx] add bx,2 loop s0 ;以上依次出栈8个字型数据到代码段0~15单元中的 ;以上依次出栈 个字型数据到代码段0~15单元中的 以上依次出栈8 mov ax,4c00h int 21h codesg ends end start ;指明程序的入口在start处 指明程序的入口在start处
6.1 在代码段中使用数据
注意在程序6.2中加入的新内容, 注意在程序6.2中加入的新内容,我们在 中加入的新内容 程序的第一条指令的前面加上了一个标 start,而这个标号在伪指令end的后 号start,而这个标号在伪指令end的后 面出现. 面出现.
6.1 在代码段中使用数据
探讨end的作用 探讨end的作用: 的作用: end 除了通知编译器程序结束外,还 除了通知编译器程序结束外, 可以通知编译器程序的入口在什么地 方.
6.1 在代码段中使用数据
汇编课件 第6章
DATA SEGMENT BIN1 DB 35H BIN2 DW 0AB48H
CUNT DB 8,16
ASCBUP DB 20H DUP(?) ADR_TAB DW 3 DUP(0) ;存放参量地址表
DATA ENDS
第二十四页,共38页。
主程序中有关指令序列修改为:
...... MOV ADR_TAB,OFFSET BIN1 ;存参量地址
源程序的数据段和堆栈安排如下:
DATA SEGMENT
BIN1 DB 35H
BIN2 DW 0AB48H
ASCBUF DB 20H DUP(?) DATA ENDS STACK1 SEGMENT PARA STACK
DW 20H DUP(0) STACK1 ENDS
由于参量的传递方式有多种形式,其相应地在子程序中取入 口参量的方法也有所不同。下面介绍三种参量的传递方法:
CALL BINASC16 ......
第二十五页,共38页。
转换子程序设置两个入口,一个是转换8位数据的入口BINASC8,另一个是 转换16位数据的入口BINASC16。
BINASC PROC
BINASC8: MOV DI,[BX];取待转换8位数据 MOV DH,[DI]
JMP TRAN
BINASC16:MOV DI,[BX] ;取待转换16位数据
第二十二页,共38页。
SP
SP+2
SP+4 SP+6 SP+8
DI
BP
DX
CX
AX
返回地址
ASCII码首址
位数
待转换数据
子程序中保存信息并 执行MOV BP,SP后
汇编语言第六章
三.中断向量表
3. 设置或取出中断向量指令 (1) 设置中断向量指令 功能:把由AL指定的中断类型的中断向量DS:DX放入中
断向量表中。
(AH)= 25H
(AL)= 中断类型号
DS:DX = 中断向量 INT 21H
三.中断向量表
(2) 取出中断向量指令
功能:把AL中指定的中断类型的中断向量从中断
一、 WIN32编程基础
(2) 循环控制伪指令
格式:.WHILE 条件表达式 循环体 .ENDW 格式:.REPEAT 循环体 .UNTIL 条件表达式 格式:.CONTINUE 功能:终止本次循环, 开始下一次循环 格式:.BREAK 功能:退出当前循环
功能:实现循环结构
一、 WIN32编程基础
内中断的处理特点: ①中断类型号一般在指令中; ② 不受中断允许标志位IF的影响。
二、 中断源
2. 外中断 由外设控制器、协处理器等CPU以外的事件引起的中断, 称为外中断。 外中断的处理特点: ① 中断类型号由8259A提供,或由自制电路来提供;
② 受中断允许标志位IF的影响(IF=1,响应中断)。
个字节。
三.中断向量表
如:INT 4AH
中断向量地址 = 4AH*4 = 128H
DEBUG执行后, 用D命令查看: ―D0:0↙ … 执行INT 4AH时: IP=1805H CS=F000H IP F000: 1805 中断处理
0:128H
0:129H
05 18
0:12AH
0:12BH
00
F0 …
外设
二、 外设与主机传送的接口与信息
接口的组成:设备状态寄存器、设备控制寄存 器、数据寄存器。 I/O端口的地址空间:允许设置64K个8位端口 或32K个16位端口。 如:40H~43H时钟/定时器,60H~63H为 8255通讯芯片的接口。
教学课件第六章汇编语言程序
返回
6.4.4 子程序设计
1. 子程序的结构 2. 设计时应解决的几个问题 3. 子程序的嵌套:其示意图见P149图6.9。 4. 递归子程序 可重入子程序
返回
设计时应解决的几个问题
1. 调用程序和子程序之间的转返 2. 调用程序和子程序之间的参数传递 3. 保护现场和恢复现场
1. 符号定义伪指令 2. 数据定义伪指令 3. 段定义伪指令 4. 模块定义伪指令 5. 设置段内偏移地址伪指令 6. 过程定义伪指令
返回
6.2 汇编语言程序结构
1. 汇编语言程序的一般结构 2. IBM—PC中程序正确返回DOS问题
返回
6.3 系统功能调用
系统功能调用含87个子程序,每个子程序对应 一个功能号。
返回
1. 01H功能调用 2. 02H功能调用 3. 05H功能调用 4. 09H功能调用 5. 0AH功能调用 6. 4CH功能调用
返回
6.4 汇编语言程序设计
6.4.1 顺序程序设计:使构成程序的三种基本 结构之一,是最简单的程序或程序块,由若干 语句线性组成。
6.4.2 分支程序设计:根据给定条件进行判定, 进而做出相应处理。其结构见P132图6.2。
6.1 汇编语言的基本语法
6.1.1 语句类别:汇编语言所使用的语句可 分为三种:指令语句、伪指令语句、宏指 令语句。 6.1.2 语句结构 6.1.3 语句中的数据项 6.1.4 汇编语言伪指令
返回
6.1.3 语句中的数据项
1. 标识符 2. 保留字 3. 表达式 4. 地址表达式
返回
6.1.4 汇编语言伪指令
汇编语言第六章.ppt
2. 输出指令 OUT
语句格式: OUT OPD,OPS 功能:累加器(OPS)→OPD
说明: ① OPD = 立即数 或者DX
② OPS只能是累加器AL、AX或EAX。
即: OUT OPD, AL/AX/EAX
例: OUT 80H,EAX 执行前: (EAX)=11223344H,(80H)=55H, (81H)=66H,(82H)=77H,(83H)=88H 执行后: (80H)=44H,(81H)=33H, (82H)=22H,(83H)=11H,(EAX)
中断前的(CS) 中断前的
(FLAGS) ┇
中断前的(IP)= 断点(IP)= 返回地址值
2. 中断返回指令
语句格式:IRET
功能:①实方式:↑(SP)→IP 32位段:↑(ESP)→EIP
②实方式:↑(SP)→CS
恢复断 点地址
32位段:↑(ESP)取低16位→CS
③实方式:↑(SP)→FLAGS
③实方式:(IP)→↓(SP),(4*n)→IP 32位段:(EIP)→↓(ESP), 从门或TSS描述符中分离出的偏移值→EIP
例: “INT 21H”用来调用DOS系统功能,每当执行这条指 令时,便产生类型号为21H的中断,执行事先安排好的中断 处理程序。堆栈中信息的布局情况如下:
┇ SP→ 中断前的(IP)
例: IN AL,60H 执行前:(60H)=11H,(AL)=0E3H 执行后:(AL)=11H,(60H)不变
说明: 60H是键盘将当前按键的键码输入到计算机内的端口的
地址。该指令语句从60H号端口中读取一个字节的键码送到 AL中,即(60H)→AL。
当(DX)=60H时, IN AL,DX 等价于 IN AL,60H
6 汇编语言高级编程
说明:如使用LOCAL伪指令,则该伪指令必须是宏定义中的第一条 指令。
18
例题6.7 定义取绝对值的宏指令。
ABS MACRO OPS
LOCAL NEXT ;定义NEXT为形参
CMP OPS,0
JGE NEXT
NEG OPS
NEXT: MOV AX,OPS ;若无LOCAL说明,宏展开后将出现标号重名
6
6.1.2 宏调用与宏展开
宏调用的格式为: <宏名> [<实参表>]
说明: ①宏名为已定义过的宏,即必须先定义、后调用。 ②实参表中的参数将一一对应替换宏定义中形参表中的参
数。两处的参数个数可以不同。若实参个数多于形式参数 个数,则多余的实参忽略;若实参个数少于形式参数个数, 则多余的形式参数用零或空格代替。 ③汇编程序在汇编源程序时,若遇到宏调用,则用调用所 提供的实参数替代相应的形参数,并把宏体中的指令嵌入 到源程序中。这种嵌入操作称为宏展开。
宏名可以与指令名或伪指令名相同,且宏名的优先级别高, 此时与其同名的指令和伪指令将失去作用。为了恢复指令 助记符和伪指令助记符的功能,就必须将宏取消,可用 PURGE伪指令实现此功能。其格式为: PURGE <宏名> [, <宏名>…]
作用:取消已经定义的宏,选用任选项时可同时取消多个宏。 例题6.8 取消例6.4和例6.7定义的宏指令
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
+
mov ah, 09h;宏调用Prompt String1的宏展开
+
lea dx, String1
第6章汇编语言程
二、常量定义伪指令
•
•
•
常量就是利用一个标识符表达的一个数值。运用符号名来表示常数,可以提高程 序的可读性和通用性。常量定义与变量定义的区别在于,常量定义不分配内存单 元。 常量定义伪指令有等价EQU和等号=,其语句格式如下: 常量名 EQU <表达式> 常量名 = <表达式> 区别:使用等号=伪指令,可以对同一个常量重复定义,后一条覆盖前一条;而 EQU则禁止重复定义。 EQU 10 AX,TEN 等价于 MOV
2019/2/5 3
.MODEL SMALL .STACK 100H .DATA S1 DB 100 DUP(5) S2 DB 100 DUP(?) .CODE .STARTUP Mov ax, ds Mov es, ax Mov cx, 50 CLD MOV SI, OFFSET S1 MOV DI, OFFSET S2 REP MOVSB Mov ah ,9 Mov dx, offset s2 Int 21h .EXIT 0 END
2019/2/5
9
6.1.3 伪指令
一、变量定义伪指令 变量的实质就是指向内存中某个地址的指针,例如定义了一 个变量VAR1,指向1000:1234内存单元。当需要访问该 单元的数据时,直接引用变量名就可以。变量的命名需符 合标识符命名规则。 变量定义伪指令就是为变量指定名称和类型,并为变量分配 存储单元,有时还直接对内存单元进行初始化,即赋值。
2019/2/5 1
机器语言:计算机能够直接识别与执行 高级语言:是完全独立于机器的通用语言,效率低, 面向过程、面向对 象,必须译成机器语言。 汇编语言:符号化语言。用指令的助记符、符号地址、标号等编写程序 的语言 。 源程序 目标模块 可执行文件
计算机组成与汇编语言第六章笔记整理
计算机组成与汇编语言笔记整理第6章:汇编语言●本章要点● 6.1 汇编语言语句● 6.1.1 汇编语言语句格式指令语句的格式:[标号:] 指令助记符[操作数[,操作数]] [;注释]伪指令语句的格式:[名字] 伪指令助记符[操作数[,操作数]] [;注释]● 6.1.2 伪指令运算符和操作数1.伪指令运算符(1)算术运算符算术运算包括:加(+)、减(-)、乘(*)、除(/)、模除(MOD)。
其中,模除(MOD)表示两整数相除后取余数。
例6.1 已知符号常量NUM=51,求下列指令的汇编结果(表达式的值):MOV AX,NUM/9MOV AX,NUM MOD 9MOV AX,NUM*5汇编的结果是:MOV AX,5MOV AX,6MOV AX,255(2)逻辑运算符和移位运算符逻辑运算包括:逻辑乘(AND)、逻辑加(OR)、按位加(XOR)和逻辑非(NOT)。
逻辑运算是按位进行的。
移位运算包括:右移(SHR)和左移(SHL),表示将二进制常量右移或左移运算符右边所规定的位数,所空出的位均补0。
例6.2 求下列指令汇编的结果。
MOV AL,4CH SHL 2MOV AL,NOT 0FFHAND AL,4CH AND 0F0HXOR AL,4CH XOR 0FFH汇编的结果是:MOV AL,30HMOV AL,0AND AL,40HXOR AL,0B3H(3)关系运算符关系运算包括:相等(EQ)、不等(NE)、小于(LT)、大于(GT)、小于等于(LE)和大于等于(GE)。
它们的运算结果是两个特殊的常量,若关系不成立,结果为0;否则结果为0FFH或0FFFFH。
例6.3 求下列指令汇编的结果。
MOV AL,4CH EQ 2MOV AL,4CH GT 1汇编的结果是:MOV AL,0MOV AL,0FFH(4)返回值运算符①取类型算符TYPE格式为:TYPE 变量或标号如果TYPE后面跟的是变量,则汇编程序将回送该变量类型的字节数:字节类型为l,字类型为2,双字类型为4,4字类型为8,10字节类型为10。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
CODE1 SEGMENT MAIN PROC FAR ASSUME CS:CODE1,DS:DATA MOV AX,DATA MOV DS,AX MOV TABLE,OFFSET ARY ;构造数组1的地址表 MOV TABLE+2,OFFSET COUNT MOV TABLE+4,OFFSET SUM LEA BX,TABLE ;传递地址表首地址 CALL FAR PTR ARY_SUM
CODE2
SEGMENT ASSUME CS:CODE2 ARY_SUM PROC FAR ;数组求和子程序 PUSH BP ;⑺保存BP值 MOV BP,SP ;BP是堆栈数据的地址指针 PUSH AX ;⑻保存寄存器内容 PUSH CX ;⑼ PUSH SI ;⑽ PUSH DI ;⑾ MOV SI,[BP+10] ;得到数组起始地址 MOV DI,[BP+8] ;得到元素个数地址 MOV CX,[DI] ;得到元素个数 MOV DI,[BP+6] ;得到和地址 XOR AX,AX
NEXT:
ADD AX,[SI] ADD SI,2 LOOP NEXT MOV [DI],AX POP DI POP SI POP CX POP AX POP BP RET 6 ARY_SUM ENDP CODE2 ENDS END MAIN
;累加 ;修改地址指针 ;存和 ;⑿恢复寄存器内容 ;⒀ ;⒁ ;⒂ ;⒃ ;⒄返回并调整SP指针
;转换千位数
;转换百位数 ;转换十位数
;转换个位数
DEC_DIV PROC ;CX中为十进制的位权 MOV AX,BX MOV DX,0 DIV CX ;商为转换后的一位十进制数 MOV BX,DX MOV DL,AL ADD DL,30H ;转换成ASCII码 MOV AH,2 ;显示 INT 21H RET DEC_DIV ENDP CODE ENDS END MAIN
2.若调用程序和子程序在同模块中, 子程序可以直接访问模块中的变量 例2.实现数组求和功能。要求数 组求和(不考虑溢出情况)由子程序实 现,其数组元素及结果均为字型数据。 见程序6.4。
程序6.4
DATA ARY COUNT SUM DATA SEGMENT DW 1,2,3,4,5,6,7,8,9,10 DW ($-ARY)/2 ;数组元素个数 DW ? ;数组和的地址 ENDS
;数组求和子程序 ;保存寄存器
;取数组起始地址 ;取元素个数 ;清0累加器
NEXT:
ADD AX,[SI] ADD SI,2 LOOP NEXT MOV SUM,AX POP SI POP CX POP AX RET ARY_SUM ENDP CODE2 ENDS END MAIN
;累加和 ;修改地址指针 ;存和 ;恢复寄存器
CODE1 SEGMENT MAIN PROC FAR ASSUME CS:CODE1,DS:DATA MOV AX,DATA MOV DS,AX CALL FAR PTR ARY_SUM MOV AX,4C00H INT 21H MAIN ENDP CODE1 ENDS
CODE2
SEGMENT ASSUME CS:CODE2 ARY_SUM PROC FAR PUSH AX PUSH CX PUSH SI LEA SI,ARY MOV CX,COUNT XOR AX,AX
程 序 6.7
STAK
SEGMENT STACK 'STK' DW 16 DUP('S') TOP EQU $ STAK ENDS DATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10 COUNT DW ($-ARY)/2 SUM DW ? DATA ENDS CODE1 SEGMENT MAIN PROC FAR ASSUME CS:CODE1,DS:DATA,SS:STAK MOV AX,DATA MOV DS,AX
第六章 子程序设计
为了程序共享或模块化设计的需 要,可以把一段公共语句序列设计成 子程序或宏指令的形式。本章介绍子 程序的设计方法。
6.1 子程序结构及设计方法 一、子程序结构 在汇编语言中用过程定义伪指令定义子程 序。过程定义伪指令格式: 过程名 PROC 属型 … 过程名 ENDP 其中过程名就是子程序名,它也表示子程序入口 的符号地址。属型可以是NEAR型(缺省值)或 FAR型。NEAR型子程序只可以被段内调用,而 FAR型子程序可以被段间或段内调用。
CODE2 ARY_SUM
SEGMENT ASSUME CS:CODE2 PROC FAR ;数组求和子程序 PUSH AX ;保存寄存器 PUSH CX PUSH SI PUSH DI MOV SI,[BX] ;取数组起始地址 MOV DI,[BX+2] ;取元素个数地址 MOV CX,[DI] ;取元素个数 MOV DI,[BX+4] ;取结果地址 XOR AX,AX ;清0累加器
3.通过地址表传递参数地址 适用于参数较多的情况。具体方法 是先建立一个地址表,该表由参数地址 构成。然后把表的首地址通过寄存器或 堆栈传递给子程序。 例3.编写一个数组求和子程序, 其数组元素及结果均为字型数据。另定 义两个数组,并编写一个主程序,通过 调用数组求和子程序分别求出两个数组 的和。
1.调用程序和子程在同一个代码段的程序结构(子 程序类型可缺省,注意END后必须跟主程序名)
CODE MAIN SEGMENT PROC FAR … CALL SUB1 RET ENDP PROC … RET ENDP ENDS END MAIN
MAIN SUB1
SUB1 CODE
2.调用程序和子程序在不同段的程序结构
例6.7.完成数组求和功能,其中求和 由子程序实现,要求使用结构访问堆栈中的 参数。 图6-3给出了堆栈及结构数据定义。注 意这些结构字段的顺序为其值压入的逆序。 实际上,它只是给图6-1中由主程序压入的数 据、返回地址及子程序压入的BP值起了个 名字而已,而字段值的预置是通过PUSH和 CALL指令实现的。当子程序用到堆栈中的 参数时,只需使用BP作为基地址、通过结 构字段名访问就可以了。编码见程序6.7。
程序6.3
STSG STSG CODE MAIN
MAIN
SEGMENT DW 32 DUP(?) ENDS SEGMENT ASSUME CS:CODE SS:STSG PROC FAR … MOV BX,162EH CALL TERN ;转换并显示 MOV AX,4C00H INT 21H ENDP
例6.6.完成数组求和功能,求和由子程序实现,要求通 过堆栈传递参数地址。 STACK SEGMENT STACK ‘STK’ DW 16 DUP(?) STACK ENDS DATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10 COUNT DW ($-ARY)/2 SUM DW ? DATA ENDS CODE1 SEGMENT MAIN PROC FAR ASSUME CS:CODE1,DS:DATA,SS:STACK
MAIN CODE1
;构造数组2的地址表 MOV TABLE,OFFSET NUM MOV TABLE+2,OFFSET CT MOV TABLE+4,OFFSET TOTAL ;传递地址表的首地址 LEA BX,TABLE ;段间调用调用数组求和子程序 CALL FAR PTR ARY_SUM MOVAX,4C00H INT 21H ENDP ENDS
注意由于堆栈操作采用后进先出的规则,一 般说来,弹出寄存器的顺序应该与压入时的 相反。
3.密切注意堆栈状态 在设计含有子程序的源程序时,要密切注 意堆栈的变化。这包括要注意一切与堆栈有关 的操作。 例如 CALL调用类型和子程序定义类型的一致性, PUSH和POP指令的匹配, 通过堆栈传递参数时子程序返回使用RET n指 令等,以确保堆栈平衡,否则后果不可预料。
6.2 子程序参数传递
可以通过给子程序传递参数使其更通 用。常用的参数传递方法如下: 通过寄存器传递; 通过地址表传递参数地址; 通过堆栈传递参数或参数地址。 另外: 若调用程序和子程序在同模块(源程序) 中,子程序可以直接访问模块中的变量;
1.通过寄存器传递
这种传递方式使用方便,适用于参数较 少的情况。 例1.把BX中的16位二进制数转换成十 进制并显示在屏幕上。 分析:二进制到十进制数的转换方法有 多种,本例采用从高到低逐个除以十进制位 权的方法。
NEXT:
ADD AX,[SI] ADD SI,2 LOOP NEXT MOV [DI],AX POP DI POP SI POP CX POP AX RET ARY_SUM ENDP CODE2 ENDS END MAIN
;累加和 ;修改地址指针 ;存和 ;恢复寄存器
4.通过堆栈传递参数或参数地址 这种方式适用于参数较多,或子程序 有多层嵌套、递归调用的情况。 步骤: 主程序把参数或参数地址压入堆栈; 子程序使用堆栈中的参数或通过栈中参数 地址取到参数; 子程序返回时使用RET n指令调整SP指 针,以便删除堆栈中已用过的参数,保持 堆栈平衡,保证程序的正确返回。
MAIN CODE1 CODE2 SUB1
SUB1 SUB2 SUB2 CODE2
二、设计子程序时应注意的问题
1.子程序说明 为便于引用,子程序应在开 头对其功能、调用参数和返回参 数等予以说明,例如参数的类型 、格式及存放位置等。
2.寄存器的保存与恢复 为了保证调用程序的寄存器内容不被 破坏,应在子程序开头保存它要用到的寄存 器内容,返回前再恢复它们。 通常用PUSH指令保存,用POP恢复。
分析:虽然主、子程序在同模块中 ,但由于在一个程序中要分别求出两个 数组的和,因此子程序不能直接引用数 组变量名。本例用数组首地址、元素个 数的地址、和地址构成地址表,通过地 址表传送这些参数的地址,以便子程序 能够访问到所需参数。见程序6.5。