第6章子程序结构 讲授要点 子程序的定义、调用与返回。 子程序的参数传递方法。 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 第6章 子程序结构 讲授要点 子程序的定义、调用与返回。 子程序的参数传递方法
6.1程序概迷 6.1.1过程的定义 过程定义由PROC与ENDP伪指令实现,形式如下: 过程名 PROC NEARJFAR 过程名ENDP 1.过程名在整个程序中必须是唯一的。 2.过程名本质上与标号一样,也具有3种属性:段地址、 偏移地址和类型(NEAR或FAR) 3.PROC后用关键字NEAR、FAR或空,以表示过程 的类型(缺省为NEAR)。 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 6.1子程序概述 6.1.1 过程的定义 过程定义由PROC与ENDP伪指令实现,形式如下: 过程名 PROC [NEAR|FAR] 过程名 ENDP 1. 过程名在整个程序中必须是唯一的。 2. 过程名本质上与标号一样,也具有3种属性:段地址、 偏移地址和类型(NEAR或FAR)。 3. PROC后用关键字NEAR、FAR或空,以表示过程 的类型(缺省为NEAR)
6.1.2过程调用和返回 1.过程调用和返回指令 (1)CALL:过程调用 与JMP指令类似,CALL指令包括下列4种调用方式: 段内直接调用( Intrasegment/ Direct call) 段间直接调用〔 Intersegment/ Direct ca 段内间接调用( Intrasegment/Indirect Cal1) 段间间接调用( Intersegment/ ndirect cal) 段内调用在同一代码段内进行,又称近(Near)调用; 段间调用可以在不同代码段之间进行,又称远(Far)调用。 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 6.1.2 过程调用和返回 1.过程调用和返回指令 (1)CALL:过程调用 与JMP指令类似,CALL指令包括下列4种调用方式: ▪ 段内直接调用(Intrasegment/Direct Call) ▪ 段间直接调用(Intersegment/Direct Call) ▪ 段内间接调用(Intrasegment/Indirect Call) ▪ 段间间接调用(Intersegment/Indirect Call) 段内调用在同一代码段内进行,又称近(Near)调用; 段间调用可以在不同代码段之间进行,又称远(Far)调用
语法格式: CALL ProcName 段內直接调用:IP进栈,IP= labell的偏移地址 段间直接调用:CS:TP进栈,CS:IP= labell的分段地址 CALL reg 16/ mem16 段内间接调用:I进栈,IP=reg16/Imem16 CALL mem32 段间间接调用:CS:I进栈,CS=mem32高字,IP=mem32低字 功能描述: (1)返回地址进栈。 远调用:CS与IP(下一条指令的地址)依次进栈 近调用:PP(下一条指令的16位偏移地址)进栈 (2)转移到过程的第1条指令去执行。 远调用:根据操作数,将32位地址送CS:IP。 近调用:根据操作数,将16位偏移地址送IP。 对标志位的影响:无。 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 语法格式: CALL ProcName 段内直接调用:IP进栈,IP= label的偏移地址; 段间直接调用:CS:IP进栈,CS:IP= label的分段地址 CALL reg16/mem16 段内间接调用:IP进栈,IP= reg16 / [mem16] CALL mem32 段间间接调用:CS:IP 进栈,CS = mem32高字,IP= mem32低字 功能描述: (1)返回地址进栈。 远调用:CS与IP(下一条指令的地址)依次进栈。 近调用:IP(下一条指令的16位偏移地址)进栈。 (2)转移到过程的第1条指令去执行。 远调用:根据操作数,将32位地址送CS:IP。 近调用:根据操作数,将16位偏移地址送IP。 对标志位的影响:无
(2)RET指令RET( Return):过程返回 语法格式: RET ;近返回或远返回 REt imm16;近返回或远返回,并调整堆栈:SP=SP+ immie 功能描述: RET:返回地址出栈,从而实现转到返回地址处。其中, 远返回:POP1个双字到CS:IP。 近返回:POP1个字到P REt imm16:在返回地址出栈后,CPU立即将imm16加到堆栈 指针SP。这种机制用来在返回前将参数从栈中移出。 对标志位的影响:无。 说明:RET由汇编程序根据其所在过程的类型(NEAR或FAR) 决定是近返回还是远返回。缺省为近返回 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 (2)RET指令RET(Return):过程返回 语法格式: RET ; 近返回或远返回 RET imm16 ; 近返回或远返回,并调整堆栈:SP = SP + imm16 功能描述: RET:返回地址出栈,从而实现转移到返回地址处。其中, 远返回:POP1个双字到CS:IP。 近返回:POP1个字到IP。 RET imm16:在返回地址出栈后,CPU立即将imm16加到堆栈 指针SP。这种机制用来在返回前将参数从栈中移出。 对标志位的影响:无。 说明:RET由汇编程序根据其所在过程的类型(NEAR或FAR) 决定是近返回还是远返回。缺省为近返回
2.使用过程应注意的问题 在过程体内必须有一条RET指令被执行到。如果在过程内没有执 行到RET或淇它转移指令,程序将继续执行ENDP后的指令。 正确选择过程的类型。通常基于下列原则: 若过程只在同一代码段中被调用,则定义为NEAR。 ·若过程可以在不同代码段中被调用,则定义为FAR 通常要保证RET指令执行前,栈顶内容正好是返回地址。 注意保护相关寄存器的值。通常,除了作为返回参数的寄存器外, 过程不应改变其它寄存器的值。 可以将过程定义放在单独的代码段中。若过程定义与主程序处于 同一代码段,则要保证其只有被调用时,才会执行。 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 2.使用过程应注意的问题 ▪ 在过程体内必须有一条RET指令被执行到。如果在过程内没有执 行到RET或其它转移指令,程序将继续执行ENDP后的指令。 ▪ 正确选择过程的类型。通常基于下列原则: • 若过程只在同一代码段中被调用,则定义为NEAR。 • 若过程可以在不同代码段中被调用,则定义为FAR。 ▪ 通常要保证RET指令执行前,栈顶内容正好是返回地址。 ▪ 注意保护相关寄存器的值。通常,除了作为返回参数的寄存器外, 过程不应改变其它寄存器的值。 ▪ 可以将过程定义放在单独的代码段中。若过程定义与主程序处于 同一代码段,则要保证其只有被调用时,才会执行
3.保存和恢复寄存器 例: SUBT PROC NEAR PUSH AX PUSH BX PUSH CX POP CX POP BX POP AX RET SUBT ENDP 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 3. 保存和恢复寄存器 例: SUBT PROC NEAR PUSH AX PUSH BX PUSH CX …… POP CX POP BX POP AX RET SUBT ENDP
【例6.1】分析下列程序,描述它的功能。 dseg SEGMENT buf db 80,81 DUP(O) dseg ENDS sseg SEGMENT STACK DW 64 DUP(O) sseg ENDS cseg SEGMENT ASSUME CS: cSeg, DS: dseg, SS: sseg 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 【例6.1】分析下列程序,描述它的功能。 dseg SEGMENT buf DB 80,81 DUP(0) dseg ENDS sseg SEGMENT STACK DW 64 DUP(0) sseg ENDS cseg SEGMENT ASSUME CS:cseg,DS:dseg,SS:sseg
cr PROC (NEAr) MOV AH.2 MOV DL 13 INT 21H MOV DL. 10 INT 21H RET cr ENDP 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 cr PROC (NEAR) MOV AH,2 MOV DL,13 INT 21H MOV DL,10 INT 21H RET cr ENDP
main: MOV AX, dseg MOV DS.AX LEA DX.buf MOV AH.10 NT 21H ;输入一个符号串 CALL cr MOV AH. NT 21H 输入一个字符 MOV BLAL 用B保存读入的字符 2021/2/19 80x86汇编语言程序设计
2021/2/19 80x86汇编语言程序设计 main:MOV AX,dseg MOV DS,AX LEA DX,buf MOV AH,10 INT 21H ;输入一个符号串 CALL cr MOV AH,1 INT 21H ;输入一个字符 MOV BL,AL ;用BL保存读入的字符