子程序结构

合集下载

第六章 子程序结构

第六章 子程序结构
段间间接远调用:CALL DST 执行操作: (SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (CS) (SP) ← (SP) - 2 ( (SP)+1,(SP) ) ← (IP) (IP) ← (EA) (CS) ← (EA+2)
2.子程序返回指令RET 返回指令为子程序最后执行的指令,作用为断点出
LENTH DW
?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
LEA SI,STRG
;SI为字符串首地址,作入口参数
CALL SCONT
;调用子程序
MOV LENTH,BX
;保存结果
MOV AH,4CH
INT 21H
第六章 子程序结构
§6.1 子程序的设计方法 §6.2 嵌套与递归子程序 §6.3 子程序举例 §6.4 DOS系统功能调用
§6.1 子程序的设计方法
➢把功能相对独立的程序段单独编写和调试, 作为一个相对独立的模块供程序使用,就形 成子程序 ➢子程序可以实现源程序的模块化,可简化 源程序结构,可以提高编程效率
SCONT NEXT:
OVER: SCONT CODE
PROC XOR CMP JZ INC INC JMP
RET ENDP ENDS END
NEAR BX,BX BYTE PTR [SI],-1 OVER BX SI NEXT
START
;BX寄存器用于统计结果 ;是否结束标志 ;是则转OVER ;统计 ;修改地址指针
分析:本题子程序的功能是统计字符串长度,只需要将被 统计字符串的首地址作为入口参数传递给子程序即可。统计的 结果放在某个寄存器如BX返回即可。程序如下:

子程序的结构

子程序的结构
<>
汇编语言程序设计
汇编语言程序设计
子程序的结构
子程序又称为过程或者函数,是一段能够独立的完成 某项功能的程序段。每一个子程序都是由子程序的定义 和子程序的调用构成。
1.子程序
子程序的结构包括: 子程序的定义;子程序的程序段;子程序的返回。 设计子程序,与程序的设计方法完全相同,可以采用顺 序、分支和循环结构;不同之处只是在于子程序的程序 段只有被调用时,其代码才能称为过程调用,本书称为主程序调用。 当主程序在需要调用子程序时,可以使用调用指令直接 调用已经定义的子程序,转去执行子程序的程序段,执 行完成后,由返回指令直接返回到主程序中调用指令的 下一条指令继续执行主程序。
3.子程序与循环结构的区别 两者都是重复执行一些相同的程序段,但循环结构每次 处理的数据都必须具有一定的规律,而子程序的程序段 每次处理的数据可以是任意的。可见,当需要对不同的 数据进行相同的处理时,应当采用子程序结构。

第6章 子程序结构

第6章 子程序结构
子程序的调用命令:CALL 子程序名, 子程序的返回命令:RET
7
6.1.3 现场保护和现场恢复的方法 ①. 在子程序中常用PUSH 指令将寄存器内容 压栈保护现场,用POP指令恢复现场。(此方法使 用方便,进栈指令和出栈指令会自动修改堆栈指 针,普遍使用) ②.在主程序中可用数据传送指令将寄存器 送到指定的存储单元中,恢复现场时再用数据传 送指令恢复的原寄存器中。(此方法使用不方 便,用得较少)
dw 10,20,30,40,50,60,70,80,90,100
count dw
sum data
10
dw ?
ends dw 100 dup (?)
stack segment tos label word
28
stack ends
code1 main
start:
segment proc far assume cs:code1,ds:data,ss:stack
22
proadd proc push push push
next:
pop si pop cx pop ax ret proadd endp code ends end start
lea mov xor add add loop mov
si, ary cx, count ax, ax ax, [si] ;求和 si, 2 next sum, ax
第六章 子程序结构(第7周:4月11计科)
6.1 6.2 6.3 子程序的设计方法 子程序的嵌套 子程序举例
1
子程结构形式
1.多处调用完成同一功能的子程:
code start: SEGMENT 、、 CALL subp 、、 CALL subp 、、 CALL subp 、、 MOV AH, 4CH INT 21H PROC 、、 、、 RET ENDP

课件-汇编语言子程序结构.ppt

课件-汇编语言子程序结构.ppt
Exit : ret Decibin endp
;每次乘的
;结果在BX中
8
Binihex proc near mov ch, 4
Rotate: mov cl, 4 rol bx, cl mov dl, bl and dl, 0fh add dl, 30h cmp dl, 3ah jl print add dl, 7h
┆ 过程名 ENDP
其中PROC表示过程定义开始,ENDP表示过程定 义结束。过程名是过程入口地址的符号表示。
一般过程名同标号一样,具有三种属性,即段 属性、偏移地址属性以及类型属性〔NEAR 和 FAR)。
2024/10/8
2
1.如果调用程序和过程在同一代码段中,那么使用NEAR属 性;

MAIN PROC FAR … CALL SUBR1 RET
sp
di
si
cx
ax
(Sp→)bp
bp
IP CS
[bp+06h] Sum地址
[bp+08h] Count地址 [bp+0ah] Ary地址
Sp
Sp Sp Sp
Sp
14
5 多个模块之间的参数传送问题
(1) PUBLIC伪指令 格式:PUBLIC 符号 [,符号] 功能:说明其后的符号是全局符号。全局符号能被其他模
Print: mov ah, 2 int 21h dec ch jnz rotate
2024/10/8 ret Binihex endp
Crlf proc near mov ah, 2 mov dl, odh int 21h mov dl, oah int 21h ret
Crlf endp
Decihex ends

第6章 子程序结构(3)

第6章   子程序结构(3)

data segment N dw 3 result db ? data ends coseg segment assume ds:data,cs:coseg main proc far start: mov ax,data mov ds,ax nov bx,N push bx call fact pop result main endp
2.子程序的递归
递归调用:子程序在嵌套调用时,直接或间接调用自身。 递归子程序:具有递归调用性质的子程序。 当子程序直接或间接地嵌套调用自身时称为递归调用, 含有递归调用的子程序称为递归子程序。递归子程序 的设计必须保证每次调用都不破坏以前调用时所用的 参数和中间笙墨,因此将调用的输入参数、寄存器内 容及中间结果都存放在堆栈中。递归子程序必须采用 寄存器或堆栈传递参数,递归深度受堆栈空间的限制。 递归子程序对应于数学上对函数的递归定义,往往 能设计出效率较高的程序,可完成相当复彖的计算9下 面以阶乘函数为例说明递归子程序的设计方法。
MOV AX,C ;第三个数C送AX CALL ABSX ADD ABS,AX ;第三个数的绝对值加到结果单元((ABS)←|A|+|B|+|C|) MOV AX,D CALL ABSX ADD ABS,AX MOV AH,4CH INT 21H
;((ABS)←|A|+|B|+|C|+|D|) ;返回DOS
DW 20H DUP(0) STAK1 ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STAK1
MAIN:MOV AX,DATA MOV DS,AX MOV AX,A ;第一个数A送AX CALL ABSX ;调用求绝对值子程序 MOV ABS,AX ;第一个数的绝对值((ABS)←|A|)送结果单元 MOV AX,B ;第二个数B送AX CALL ABSX ;调用求绝对值子程序 ADD ABS,AX ;第二个数的绝对值加到结果单元((ABS)←|A|+|B|)

第6章子程序结构

第6章子程序结构

第6章 子程序结构
子程序定义伪操作用在子程序的前后, 子程序定义伪操作用在子程序的前后 , 使整个子 程序形成清晰的、具有特定功能的代码块。 程序形成清晰的、具有特定功能的代码块。其格式为 PROCEDURE NAME PROC ATTRIBUTE PROCEDURE NAME ENDP
第6章 子程序结构
第6章 子程序结构
主主主 1 调调子主主 2 3 调调子主主 1 调调子主主 2 3 返返 子主主
图6.1 主程序与子程序之间的关系
第6章 子程序结构
子程序具有如下4个特性: 子程序具有如下 个特性: 个特性 (1) 重复性。一个子程序只占用一段存储区域,但 重复性。一个子程序只占用一段存储区域, 可以多次被调用,避免了编程人员的重复劳动,又节 可以多次被调用, 避免了编程人员的重复劳动, 省程序的存储空间。由于增加了调用、返回等指令, 省程序的存储空间 。 由于增加了调用 、 返回等指令 , 因此程序执行时间会长些。 因此程序执行时间会长些 。 如果一个程序段只用到一 次,就没有必要编写成子程序形式。 就没有必要编写成子程序形式。
第6章 子程序结构
(3) 可浮动性。所谓可浮动性,就是说子程序可以 可浮动性。所谓可浮动性, 存放在存储区的任何地址处。 存放在存储区的任何地址处 。 假如子程序只能存放在 固定的地址处, 固定的地址处 , 则在编写主程序时要特别注意存储单 元的分配, 元的分配 , 不要使主程序占用了子程序的存储单元而 破坏掉子程序,这样就会给编程人员带来很大麻烦, 破坏掉子程序 , 这样就会给编程人员带来很大麻烦 , 而且在装配主程序和子程序时往往造成存储空间的冲 突或浪费。 突或浪费。
其中, 子程序名为标识符, 其中 , 子程序名为标识符 , 它又是子程序入口的 符号地址。它的写法与标号的写法相同。属性 (Attribute)是指子程序的类型属性 , 可以是 是指子程序的类型属性, 可以是NEAR或 是指子程序的类型属性 或 FAR。 。 如前所述, 指令都有NEAR和FAR的 如前所述,CALL和RET指令都有 和 指令都有 和 的 属性。段内调用使用 属性, 属性。段内调用使用NEAR属性,但可以隐含;段间 属性 但可以隐含; 调用使用FAR属性。为了使用户的工作更方便,80x86 属性。为了使用户的工作更方便, 调用使用 属性 的汇编程序用PROC伪操作的类型属性来确定 伪操作的类型属性来确定CALL和 的汇编程序用 伪操作的类型属性来确定 和 RET指令的属性。也就是说,如果所定义的子程序是 指令的属性。也就是说, 指令的属性 FAR属性的,那么对它的调用和返回一定都是FAR属 属性的,那么对它的调用和返回一定都是 属性的 属 性的; 性的;

第6章 子程序结构

第6章 子程序结构

例6.5 三个模块中的外部符号定义。 ; source module 1 extrn var2:word,lab2:far public var1,var4,lab1 data1 segment var1 db ? var3 dw ? var4 dw ? data1 ends code1 segment assume cs:code1,ds:data1 main proc far start: mov ax,data1 mov ds,ax ; ...... lab1: ; ...... mov ax,4c00h int 21h main endp code1 ends end start
6.1.3 保存与恢复寄存器 由于调用程序(又称主程序)和 子程序经常是分别编制的,所以 它们所使用的寄存器往往会发生 冲突。 如果主程序在调用子程序以前的 某个寄存器内容在从子程序返回 后还有用,而子程序又恰好使用 了同一寄存器,造成破坏了寄存 器的原有内容,那就会造成程序 运行错误,这是不允许的。
1.通过寄存器传送变量
开始 从键盘收得十进制 数保存在BX中
例6.3十进制到十六进 制数转换程序。程序 要求从键盘取得一个 十进制数,然后把该 数以十六进制形式在 屏幕上显示出来。
程序结构
通用DECIBIN
通用CRLF 显示回车换行 通用BINIHEX 用十六制数形式 显示BX中的数
通用CRLF
结束
pop
ret proadd endp
ax
;恢复寄存器
;功能:将BX的内容按4位十六进制数格式 输出
;入口条件:BX中存放待输出的数据
binihex proc push push push mov rotate: mov rol mov and near ax cx dx ch,4 cl,4 bx,cl al,bl al,0fh ;数据位数 ;循环移位次数 ;向左循环移位,将高四位移到低四位 ;取低字节到AL ;屏蔽高四位,截取低四位 ;保护寄存器

第六章 子程序结构

第六章  子程序结构

• • • • • • • • • • •
CODE SEGMENT ASSUME DS : DATA , CS : CODE , SS : STACK START: MOV AX,DATA MOV DS,AX MOV DX,0 MOV DL,NUM8 ;转换二进制数送DX MOV CX,8 ;置位数8 LEA DI,ASCBUF ;字符串首址→DI CALL BTASC ;调用子程序BTASC MOV [DI],BYTE PTR 0DH MOV [DI+1],BYTE PTR 0AH
• • • • • • • • • STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS DATA SEGMENT N DW 5 RESULT DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE, SS:STACK,DS: DATA
• 【例】试编制计算N! (N≥0)的程序。N!=N* (N-1)*(N-2)*……*1 • 其递归定义如下: • 0!=1 • N!=N*(N-1)! (N>1) • 计算N!的子程序FACT的流程图如图4.10所示。
【例】计算5!的程序示例, RESULT是保存阶乘的存 储单元。 程序如下:
子程序设计方法
• 信息的保护与恢复 • 主程序与子程序参数传递方式
信息的保护与恢复

• • • • • •
例如:若子程序PROG中改变了寄存 器AX,BX,CX,DX的值,则可采用 如下方法保护和恢复现场。 PROG PROC PUSH AX PUSH BX PUSH CX ;保护现场 PUSH DX ┆
• • • •
• • • • • •
入口参数:DX存放待转换的二进制数 CX存放待转换数的位数(8位或16位) DI存放ASCII码首地址 出口参数:转换后的字符串存放在以DI作指针的字 节存贮区中 程序如下: DATA SEGMENT NUM8 DB 93H NUM16 DW 0ABCDH ASCBUF DB 20 DUP(0) DATA ENDS

汇编子程序的一般结构组成。

汇编子程序的一般结构组成。

汇编子程序的一般结构组成。

汇编子程序是一段独立的程序代码,可以被其他程序调用。

它的一般结构由以下几个部分组成:
1. 子程序头部:包括子程序的名称、输入参数和输出参数的说
明等。

2. 参数传递:子程序的输入参数和输出参数通过栈或寄存器传递。

3. 保存寄存器:在进入子程序之前,需要保存一些寄存器的值,以免在执行子程序时被覆盖。

4. 执行程序:这是子程序的核心部分,实现子程序的功能。

5. 恢复寄存器:在退出子程序之前,需要还原保存的寄存器的值。

6. 返回值:如果子程序有返回值,需要将其保存在寄存器或栈中,并通过ret指令返回给调用程序。

以上是汇编子程序的一般结构组成,不同的子程序可能会有差异。

编写子程序需要熟悉汇编语言的基础知识和调试技巧,能够理解程序的逻辑思路、掌握数据结构和算法,才能编写出高效、稳定的子程序。

- 1 -。

第六章 子程序结构

第六章  子程序结构

第六章 子程序结构一、主程序与子程序的概念子程序又称为过程,它相当于高级语言中的过程和函数。

通常,凡是具有相对独立功能的程序段或需要多次应用的程序段都可以编制成子程序。

程序中当需要这段程序时,用调用指令CALL 转到这段程序中去,执行完毕,通过RET 指令返回原来的程序。

如下图(1)所示。

子程序返回后,从CALL 的下一条指令X 1继续执行主程序。

使用子程序优点:节省编程时间和存储空间,有利于设计一个大而复杂的程序。

即可以把一个大而复杂的程序设计成由一个主程序和若干个子程序组成,使用模块化程序设计,减少程序设计复杂性。

使用子程序不足之处:在调用和返回时要进行堆栈操作,增加CPU 开销,使程序速度减慢。

继续SURENDP X 1: (1)主程序与子程序的关系(2)子程序嵌套调用主程序与子程序的概念是相对的。

图(2)是一个子程序嵌套调用的例子。

图中,程序1在A、B两处调用程序2,在C处调用程序3,则称程序2和3是程序1的子程序,程序1是主程序;而程序2和3又分别调用程序4,则称程序4是程序2和3的子程序,程序2和3是主程序。

这就是子程序中嵌套子程序。

子程序还可以直接或间接调用自己,称为递归子程序和递归调用。

二、调用指令CALL 和返回指令RET(参见指令系统p.98)CALL 调用指令RET 返回指令由于子程序和调用程序可以在同一个段中,也可以不在同一段中,因此这两条指令的格式如下:1、调用指令CALL DSTCALL指令语句实现子程序(即过程)的调用。

调用结束后,要由所调用的子程序RET指令返回到CALL指令的下一条指令(即返回调用断点),因此执行CALL指令时要进行进栈操作。

具体分为直接调用和间接调用。

直接调用:目标地址直接出现在CALL指令语句中,DST就是过程名(即子程序名)。

间接调用:由16位通用寄存器或者存储单元提供调用地址。

(1)段内直接调用格式:CALL DST执行的操作:Push(IP) ;当前IP值进栈(IP)←(IP)+D16;目标地址装入IP,程序转移指令操作分二步:第一步,是把子程序的返回地址(即调用程序中CALL指令的下一条指令的地址)存入堆栈中,以供子程序返回主程序时使用。

第6章 子程序结构

第6章 子程序结构

Lea dx,string地址 地址(IP) 地址 Num string地址 地址
2010-12-28 ch6
从键盘取得十进制 保存到BX BX中 数,保存到BX中 显示回车和换行 用十六进制形式 显示BX BX中的数 显示BX中的数
7
计算机科学与技术系
《汇编语言》 汇编语言》
Decihex
segment
assume cs:Decihex Main proc far Repeat: push ds xor ax, ax push ax call decibin call crlf call binihex call crlf ret Main endp
通过堆栈传递地址或参数
计算机科学与技术系
《汇编语言》 汇编语言》
Binhex proc near push bp mov bp,sp push ax push di push bx push cx pushf mov ax, [bp+4] mov di, [bp+6] mov ch, 4 mov cl, 4 roat: rol ax ,cl mov bl, al and bl, 0fh add bl, 30h cmp bl, 39h jle next add bl, 7h 2010-12-28
;每次乘的 每次乘的
;结果在 中 结果在BX中 结果在
8
计算机科学与技术系
《汇编语言》 汇编语言》
Binihex proc near mov ch, 4 Rotate: mov cl, 4 rol bx, cl mov dl, bl and dl, 0fh add dl, 30h cmp dl, 3ah jl print add dl, 7h Print: mov ah, 2 int 21h dec ch jnz rotate ret 2010-12-28 Binihex endp

5第五章 程序篇-子程序结构

5第五章 程序篇-子程序结构

19
data ary count sum data
segment dw 100 dw 100 dw ? ends
dup(?)
20
子程序proadd结构 保护现场 push ax push cx push si lea si, mov cx, xor ax, add ax, add si, loop next mov sum, pop si pop cx pop ax
调用程序在调用子程序时,经常需要传送一些参数给子
程序;子程序运行完后也经常要回送一些信息给调用程 序。
参数传送(参数传送、过程通信):调用程序和子程序
之间的信息传送。
9
1、通过寄存器传送变量: 利用寄存器在主—子程序之间传送数信息。
例、十进制到十六进制转换程序。 程序要求从键盘取得一个十进制数,然后把该数以十六进制 形式在屏幕上显示出来。
23
3、通过堆栈传送参数或参数地址 在主程序中把参数地址保存到堆栈,在子程序里从堆栈 中取出参数以达到传送参数的目的。
24
注:①在主程序中将数组情况入栈:(将数组的地址入栈) Mov Push Mov Push Mov Push bx, bx bx, bx bx, bx offset ary offset count offset sum
7

注意:
主程序可看成DOS的一个子过程,故用FAR属性。 子程序的调用和返回已包括了返回地址的出、入栈,故 在子程序中必须正确使用堆栈,否则将造成运行错误。 在一进入子程序后应该将子程序所需要使用的寄存器内 容保存在堆栈中,在退出子程序前把寄存器内容恢复原状。
8
二、主程序与子程序的参数传送
MAIN ENDP
5
例2、调用程序和子程序不在同一个代码段中。 SEG1 SEGMENT ┆ SUB1 PROC FAR ┆ RET SUB1 ENDP ┆ CALL SUB1 ┆ SEG1 ENDS

第6章 子程序结构(1)

第6章   子程序结构(1)

aldispl:mov ah,2 ;显示 int 21h pop dx ;恢复原ax值到dx and dl,0fh ;转换al的低4位 or d1,30h cmp d1,39h jbe aldisp2 add dl,7
aldisp2: mov ah,2 :显示 int 21h pop dx pop cx pop ax ret ;过程返回 LDisp endp
带立即数的返回指令的出栈操作示意图
在MASM 5.0及其以后版本中,可用指令RETN或 RETF来显式地告诉汇编程序是本子程序的返 回是近返回,还是远返回。 例如: RET ;可能是近返回,也可能是远返回 RETN ;近返回指令 RETF ;远返回指令 RET 6 ;子程序返回后,(SP)←(SP) + 6
2)程序(过程)返回 RET 格式:RET [n] RET 必须是子程序中最后执行的一条指 令,用来返回调用程序的断点处( CALL 的下 一条指令)。将返回地址出栈送入IP 寄存器; 段间调用还需将CS寄存器恢复。 程序有多个出口,则可有多个RET。
子程序被定义为 NEAR属性,汇编时汇编段内返回指 令编码,CPU执行RET时,将当前栈顶的内容送入 IP。 子程序被定义为FAR属性,汇编时汇编段间返回指令 编码, CPU 执行 RET 时,将当前栈顶连续 4 个字节 的内容分别送入IP、CS。 (1)段内返回 格式:RET 结果: (IP)←(SP)+1和(SP) ;(将栈顶字单元内容弹出,装入IP) (SP)←(SP)+2 ;(SP内容+2,指向新的栈顶)
StrLen PROC PUSH PUSH XOR XOR MOV again: CMP JZ INC INC JMP over: POP POP RET StrLen ENDP

[汇编]子程序结构

[汇编]子程序结构

[汇编]子程序结构子程序又称为过程,相当于高级语言中的过程和函数。

在一个程序的不同部分,往往要用到"类似"的程序段,即这些程序段的功能和结构形式都相同,只是某些变量赋值不同。

此时就可以把这些程序段写成子程序形式,以便需要时调用它。

有些程序段对于某个用户可能只用到一次,但它是一般用户经常用到的,如十进制数转换成二进制数,二进制数转换为十六进制数并显示输出等。

对于这些常用的特定功能的程序段,经常编制成子程序供用户使用。

此外,子程序结构还是模块化程序设计的重要工具,后面将介绍模块化程序设计方法。

1 过程定义伪操作过程定义伪操作用在过程(子程序)的前后,使整个过程形成清晰的、具有特定功能的代码块。

其格式为:procedure name PROC Attribute……procedure name ENDP其中过程名为标识符,它又是子程序入口的符号地址,与标号的作用相同。

属性(Attribute)是指类型属性,可以是NEAR或FAR。

用户对过程属性的确定原则很简单,即:(1)如果调用程序和过程在同一个代码段中,则使用NEAR属性。

(2)如果调用程序和过程不在同一个代码段中,则使用FAR属性。

2 子程序的调用和返回子程序的正确调用和正确返回可以保证过程的正确执行,这一功能由8086的CALL和RET指令完成。

为保证其正确性,除PROC的属性要正确选择外,还应该注意子程序运行期间的堆栈状态。

由于CALL时已使返回地址入栈,所以RET时应该使返回地址出栈。

如果子程序中不能正确使用堆栈而造成执行RET前SP并未指向进入子程序时的返回地址,则必然会导致运行出错,因此子程序中对堆栈的使用应该特别小心,以免发生错误。

3 保存与恢复寄存器由于调用程序(又称主程序)和子程序经常是分别编制的,所以它们所使用的寄存器往往会发生冲突。

如果主程序在调用子程序之前的某个寄存器内容在从子程序返回后还有用,而子程序又恰好使用了同一个寄存器,这就破坏了该寄存器的原有内容,因而会造成程序运行错误,这是不允许的。

第六章 子程序结构

第六章 子程序结构

4、通过堆栈传递参数或参数地址 例6.4.3 求数组ary中所有元素之和,结果存入指定内存单元sum。 注意语句: mov bx,offset ary ;参数地址入栈 push bx mov bx,offset count push bx mov bx,offset sum push bx call far ptr proadd ;注意是far …… mov si,[bp+0ah] ;从栈中取得参数地址 mov di,[bp+8] mov cx,[di] mov di,[bp+6] …… ret 6 段内调用call,则push(ip) 返回ret,则pop(ip) 段间调用call,则push(cs),push(ip)返回ret,则pop(ip), pop(cs) 若ret后有数字n,表示返回后,sp<-sp+n
POP BX POP CX POP DX RET SUBT ENDP
四、子程序的参数传送 调用程序与子程序之间的信息传送称为参数传送(也称变量传送) 参数传送方式主要有4种:寄存器、直接变量、地址表、堆栈 1、通过寄存器传递参数 只在参数较少时使用,如1个参数。 例6.3 从键盘取得一个10进制数,然后把该数以16进制形式在屏幕 上显示。
第三节 子程序举例 例6.9 把键盘输入的16进制正数转换为10进制数并在屏幕上显示
例6.10 键盘输入数字(0-9),显示该数字对应的字符串 框图:
例6.11 键盘输入人名(最多30个),升序排序并显示 框图:
第六章 子程序结构 本章重点:寄存器恢复与保存;利用堆栈送参数 子程序:程序的不同部分用到相同的程序段,这些程序段 的功能和结构形式都相同,只是某些变量的赋值不同, 此时可以将程序段写成子程序形式,以便需要时调用。 第一节 子程序的设计方法 一、过程定义伪操作 子程序名 proc 属性 …… 子程序名 endp 其中属性使用:若调用程序与子程序在同一代码段,使用 NEAR;若调用程序与子程序不在同一代码段,使用 FAR属性

子程序结构

子程序结构

第六章子程序结构§6.1 子程序的设计方法一、过程定义伪指令格式:〈过程名〉PROC NEAR、FAR……RET〈过程名〉ENDP指令组中至少有一个返回指令,通常用RET过程名是子程序的地址符号名,与段名、变量名等定义和作用类似。

子程序的调用使用CALL指令,返回使用RET指令。

过程名是CALL指令的操作数,有三个属性:段地址、偏移地址和类型,类型有两种:NEAR , FAR。

其中NEAR为缺省。

其类型决定了CALL和RET指令的目标码是段内或段间调用或返回。

CALL的寻址方式和JMP相似,它们都是对地址的修改。

书P80,吴秀清书P104。

调子程序的格式:段内调用及返回(修改IP单字操作)CALL PROG_N(过程名);CALL BX;CALL WORD PTR [BX+SI+D]RETRET n段间调用(修改IP CS 双字操作)CALL FAR PTR PROG_F(过程名)CALL DWORD PTR [BX+SI+D]RETRET n子程序在程序中的应用:举例L600.doc二、子程序的调用与返回1、调用:CALL2、返回:RETRET n三、编程原则1、类型定义:主程序为FAR型,子程序调用与定义在同一代码段的用NEAR;调用与定义在不同代码段的用FAR2、程序结构✓主程序与子程序顺序排列:一般主程序在前,子程序在后。

✓子程序中的堆栈操作一定要匹配PUSH指令,及对象和POP指令对应。

3、入口/出口参数及现场保护入口参数:调用者提供给子程序的信息出口参数:子程序运行后,返给调用者的信息。

参数传递:调用者与子程序之间信息传递的方法。

由于寄存器数量有限,为了避免冲突,提高子程序的通用性,所以编写子程序时应保护除入口/出口参数之外所用到的所有寄存器。

4、子程序说明子程序名、功能、入口参数、出口参数、执行时间等四、参数传递方法:✧寄存器传送✧变量传送✧参数表传送✧堆栈传送1、用寄存器传送:适用于参数较少的情况,即入口参数例如书200,例6.3题,子程序DECIBIN从键盘输入的数放在BX中,主程序在调用子程序BINIHEX前,是让它将BX的内容转换为十六进制显示。

第六章 子程序结构

第六章  子程序结构

执行的操作为:(SP)←(SP)-2 (SP) SP)-2 )- PUSH CS ((SP +1,(SP)) SP) ,(SP))← CS) ((SP)+1,(SP))←(CS) SP) SP)- )-2 (SP)←(SP)-2 PUSH IP ((SP +1,(SP)) SP) ,(SP))← IP) ((SP)+1,(SP))←(IP) IP) (IP)←DST指定的偏移地址 CS) (CS)←DST指定的段地址
调用程序:编制程序时,按需要转向子程序,称为子程序调用,或称为 : 过程调用。调用子程序的程序称为调用程序或主程序。主、子程序是 相对而言的。但子程序一定是受调用程序或主程序调用的。
一、过程调用与返回指令
1.过程调用指令CALL 过程调用指令CALL 过程调用指令
指令格式: 指令格式: CALL DST 其中DST为过程的目标地址。
如下面的定义皆为正确的过程定义:
(1)段内调用: A PROC NEAR …… A ENDP (2)段间调用: B PROC FAR ……. B ENDP A PROC …… A ENDP

code main
segment proc far …… call subr1 …… ret endp
segx subt
2.返回指令 返回指令RET 返回指令
指令格式: 指令格式:RET
指令功能: 指令功能:RET指令通常写在一个子程序(或过程)的最后,用以 返回到调用这个子程序的断点处。 RET指令也属于无条件转移指令。可以在段内或段间返回。
(1)段内返回
RET指令由堆栈弹回断点偏移量到指令指针IP,实现段内调用返回。
执行的操作为: IP) ((SP +1,(SP)) SP) ,(SP)); (IP)←((SP)+1,(SP)); POP IP SP) SP) (SP)←(SP)+2 ;

第4章 子程序结构

第4章 子程序结构

(BX)
开始 十进制数转换为 二进制数
【例 1】 模块图
调用dec2bin:从键盘输入十 进制数,保存在BX中。 进制数,保存在BX中
另起一行
调用crlf:显示回车和换行。 显示回车和换行。
二进制数转换为 十六进制数并显示 调用bin2hex:用十六进制形 式显示BX中的数。 式显示BX中的数。 中的数 另起一行
n
第4章 子程序结构
3. 通过地址表传送参数地址
code segment org 100h assume cs:code, ds:data, ss:data main proc far …… mov table, offset ary mov table+2, offset count mov table+4, offset sum mov bx, offset table call proadd …… main endp proadd proc near …… mov si, [bx] mov di, [bx+2] mov cx, [di] mov di, [bx+4] xor ax, ax next : add ax, [si] add si, 2 loop next mov [di], ax …… proadd endp
第4章 子程序结构
2. 子程序直接访问统一模块中的变量
data segment 低 低 ary dw 100 dup(?) ary ary count dw 100 sum dw ? data ends count …… …… code segment main proc far assume cs:code, ds:data start : sum…… sum call near ptr proadd …… 高 高 main endp proadd proc 低 near …… num lea si, ary mov cx, count xor ax, ax count [si] next : add ax,…… add si, 2 loop next mov sum, ax sum, …… total proadd endp code ends 高 end start
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
① 数据本身(传值) ② 数据的地址(传址)
传递的方法:
① 寄存器 ② 变量 ③ 堆栈
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)
方法一:用寄存器传递参数
相关文档
最新文档