子程序结构

合集下载

第六章 子程序结构

第六章 子程序结构
段间间接远调用: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. 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)
方法一:用寄存器传递参数
相关文档
最新文档