子程序结构
① 数据本身(传值) ② 数据的地址(传址)
传递的方法:
① 寄存器 ② 变量 ③ 堆栈
13
例:将两个给定的二进制数转换成为二进制数的ASCII 码形式并加以显示
对两个数进行转换、显示的工作是相同的,没有必要重 复编写,以子程序的形式来完成 转换子程序需被告知:
被转换的数及其长度 存放结果的起始位置 被显示内容的起始位置
;无参数段内返回 ;有参数段内返回 ;无参数段间返回 ;有参数段间返回
需要弹出CALL指令压入堆栈的返回地址
段内返回——偏移地址IP出栈 IP←SS:[SP], SP←SP+2 段间返回——偏移地址IP和段地址CS出栈 IP←SS:[SP],SP←SP+2 CS←SS:[SP],SP←SP+2
在主程序中进行
在子程序中进行
10
三、现场的保护与恢复
…… PUSH BX PUSH AX CALL SUB1 POP AX
—在主程序中进行
注意: 进栈/出栈的顺序 保护与恢复的对象: 主程序用到的存有数据、中间结果且 在CALL指令后还要用到的R/M
POP BX
……
11
三、现场的保护与恢复
5
一、子程序指令—返回指令RET的参数
RET i16 ;有参数返回 RET指令可以带有一个立即数i16,则堆栈指针SP将增加 ,即 SP←SP+i16
这个特点使得程序可以方便地废除若干执行CALL指令以 前入栈的参数
6
二、子程序的调用与返回
主程序
子程序
CALL label RET
回到CALL指令后的指令处 ——返回地址
3
一、子程序指令—调用指令
CALL指令分成4种类型(类似JMP)
CALL label CALL r16/m16 CALL far ptr label CALL far ptr mem
;段内调用、直接寻址 ;段内调用、间接寻址 ;段间调用、直接寻址 ;段间调用、间接寻址
CALL指令需要保存返回地址:
MOV AH,2 MOV DL,[DI] INT 21H INC DI LOOP REP2 MOV DL,0AH MOV AH,2 INT 21H MOV DL,0DH MOV AH,2 INT 21H RET ENDP ENDP ENDS END MAIN
;设置显示后的光标位置
;set entry point
15
BH
;转换子程序 BINASC PROC REP1: ROL BX,1 MOV DL,BL AND DL,01H ADD DL,30H MOV [DI],DL INC DI
BL
DL
DI
;屏蔽除最低位外的其他位
LOOP REP1
RET BINASC ENDP
16
;显示子程序 DISP PROC MOV DL,[DI] INT 21H INC DI LOOP REP2 MOV DL,0AH ;设置显示后的光标位置 REP2: MOV AH,2
AX
DI 进入子程序时的SP IP 长度 地址 BIN1 BP+14 BP+16
BP+18
22
§6.2 嵌套与递归子程序
嵌套:子程序调用其他子程序,嵌套层数取决 于堆栈的大小32K(基本不受限制) 递归:子程序调用自己,该情况要合理设置出 口参数,否则会造成程序死锁
23
§6.3 子程序举例
十六进制数显示的实现
4
BHH4 BHL4 BLH4 BLL4 BHL4 BLH4 BLL4 BHH4
从 最 高 位 开 始
AL
BHH4
26
;例6-3,十进制到十六进制数的转换 SSEG SEGMENT PARA STACK 'STACK' DW 100H DUP(0) SSEG ENDS DSEG SEGMENT PARA 'DATA' DSEG ENDS CSEG SEGMENT PARA 'CODE’ ASSUME CS:CSEG, DS:DSEG,SS:SSEG MAIN PROC FAR MOV AX,DSEG ;MAKE NECCESSARY INITALIZALITION MOV DS,AX REPEAT: CALL DECIBIN CALL CRLF CALL BINIHEX CALL CRLF JMP REPEAT MOV AH,0AH INT 21H MOV AX,4C00H INT 21H ENDP ;RETURN DOS
从 最 低 位 开 始
= 12CH = 7D0H =2710H =3039H
30
增强功能的过程定义伪操作
格式:
PROCNAME PROCNAME PROC [ATTRIBUTES FIELD] [USES REGISTER LIST] [,PARAMETER FIELD]
……
ENDP
ATTRIBUTES FIELD :
MOV CH,4
ROTATE: MOV CL,4 ROL BX,CL MOV AL,BL
;共四位十六进制数
;从最高位开始,将其移位至BX,AL的低4位
AND AL,0FH ADD AL,30H CMP AL,3AH JL PRINTIT ADD AL,7 PRINTIT: MOV DL,AL MOV AH,2 INT 21H DEC CH JNZ ROTATE RET BINIHEX ENDP
MOV AH,2
INT 21H MOV DL,0DH
MOV AH,2
INT 21H RET
DISP
ENDP
17
DSEG BIN1 BIN2 ASCBUF DSEG CSEG MAIN
SEGMENT PARA 'DATA' DB 35H DW 0AB48H DB 20H DUP(?) ENDS SEGMENT PARA 'CODE' ASSUME CS:CSEG, DS:DSEG,SS:SSEG PROC FAR MOV AX,DSEG MOV DS,AX MOV BH,BIN1 MOV CX,8 LEA DI,ASCBUF PUSH DI PUSH CX CALL BINASC POP CX POP DI PUSH DI CALL DISP POP DI ADD DI,10H MOV BX,BIN2 MOV CX,16 PUSH DI PUSH CX CALL BINASC POP CX POP DI CALL DISP MOV AX,4C00H INT 21H
7
二、子程序的调用与返回 —书写形式(同一代码段内)
8
二、子程序的调用与返回 —书写形式(不同代码段)
9
三、现场的保护与恢复
现场:主程序转向子程序之前,其所使用的一些资 源的状态(如标志位、R/M等) 子程序与主程序分别编制,通常会导致使用的资源 发生冲突而影响主程序在调用子程序之后的正确执 行 方法:利用堆栈
DISTANCE
LANGUAGE TYPE VISIBILITY
PROLOGUE
31Байду номын сангаас
增强功能的过程定义伪操作
32
例6.8
.MODEL SMALL .STACK 64 .DATA ASCVAL DB '12345' BINVAL DW ? .CODE MAIN PROC FAR MOV AX,@DATA MOV DS,AX LEA BX,ASCVAL PUSH BX LEA BX,BINVAL PUSH BX CALL CONVASCBIN MOV BX,BINVAL CALL BINIHEX
SUB1 PROC
—在子程序中进行
PUSH BX
PUSH AX …… POP AX POP BX
注意: 进栈/出栈的顺序
保护与恢复的对象: 子程序用到的R/M
RET
SUB1 ENDP
12
四、子程序参数的传递
入口参数(输入参数):主程序提供给子程序
出口参数(输出参数):子程序返回给主程序
参数的形式:
第六章 子程序结构
§6.1 子程序的设计方法
§6.2 嵌套与递归子程序
§6.3 子程序举例 §6.4 DOS系统功能调用
1
§6.1 子程序的设计方法
一、子程序指令
二、子程序的调用与返回
三、现场的保护与恢复 四、子程序参数的传递
2
一、子程序指令
子程序是完成特定功能的一段程序 当主程序(调用程序)需要执行这个功能时,采用 CALL调用指令转移到该子程序的起始处执行 当运行完子程序功能后,采用RET返回指令回到主程 序继续执行
24
例 6.3 十进制到十六进制数的转换 (从键盘取得一个十进制数,然后把该数以十六进制的形式 在屏幕上显示出来)
25
例 6.3 十进制到十六进制数的转换(6-3-1.DOC)
转换方法:
‘1234’ ((((0*10+1)*10)+2)*10+3)*10+4 从最高位开始:累加和*10+本位的权值
段内调用——偏移地址IP入栈 SP←SP-2,SS:[SP]←IP 段间调用——偏移地址IP和段地址CS入栈 SP←SP-2,SS:[SP]← CS SP←SP-2,SS:[SP]← IP
4
一、子程序指令—返回指令
根据段内和段间、有无参数,分成4种类型
RET RET i16 RET RET i16
显示子程序需被告知:
被显示内容的长度
14
例:将两个给定的二进制数转换成为二进制数的ASCII 码形式并加以显示(6-1-1.asm)
方法一:用寄存器传递参数