第六章 子程序结构

25
汇汇汇汇汇汇汇汇 汇汇汇 汇汇汇汇汇 汇汇汇 汇汇汇汇汇 汇汇汇汇汇汇汇 汇汇汇汇汇汇汇汇汇 汇汇汇汇汇汇汇汇 汇汇汇汇汇汇 汇汇汇汇汇汇汇汇汇

Upload: delila

Post on 21-Jan-2016

116 views

Category:

Documents


0 download

DESCRIPTION

第六章 子程序结构.  过程定义伪操作  子程序的调用与返回  保存与恢复寄存器  子程序的参数传送  子程序的嵌套与递归. 过程名 PROC NEAR ( FAR ) 过程名 ENDP ( 1 ) NEAR 属性:调用程序和子程序在同一代码段中 (段内调用) ( 2 ) FAR 属性:调用程序和子程序不在同一代码段中 (段间调用). 1. 过程定义伪操作. code segment main proc far …… - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构

第六章 子程序结构

过程定义伪操作 子程序的调用与返回 保存与恢复寄存器 子程序的参数传送 子程序的嵌套与递归

Page 2: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构

1. 过程定义伪操作 过程名 PROC NEAR ( FAR )

过程名 ENDP

( 1 ) NEAR 属性:调用程序和子程序在同一代码段中

(段内调用)

( 2 ) FAR 属性:调用程序和子程序不在同一代码段中

(段间调用)

.

.

.

Page 3: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构code segment main proc far …… call subr1 …… retmain endp

subr1 proc near …… retsubr1 endp

code ends

segx segmentsubt proc far …… retsubt endp …… call subt ……segx ends

segy segment …… call far ptr subt ……segy ends

Page 4: 第六章   子程序结构

子程序调用:隐含使用堆栈保存返回地址 call near ptr subp

(1) 保存返回地址 (2) 转子程序

call far ptr subp

(1) 保存返回地址 (2) 转子程序

子程序返回: ret

2. 子程序的调用与返回

(SP)→ (IP)

(IP)

(CS)

(SP)→

Page 5: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构

3. 保存与恢复寄存器 subt proc far

push ax push bx push cx push dx …… …… pop dx pop cx pop bx pop ax

retsubt endp

Page 6: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构

(1) 通过寄存器传送参数

(2) 通过存储器传送参数

(3) 通过地址表传送参数地址

(4) 通过堆栈传送参数或参数地址

(5) 多个模块之间的参数传送

4. 子程序的参数传送

Page 7: 第六章   子程序结构

例:十六进制到十进制的转换(通过寄存器传送参数)

hexidec segment ; 1610 assume cs: hexidec main proc farstart: push ds

sub ax, ax push ax

repeat: call hexibin ; 162 call crlf call binidec ; 210 call crlf jmp repeat ret

main endp………………hexidec ends

end start

Page 8: 第六章   子程序结构

hexibin proc near mov bx, 0newchar:

mov ah, 1 int 21h sub al, 30h jl exit cmp al, 10 jl add_to sub al, 27h cmp al, 0ah jl exit cmp al, 10h jge exit

add_to: mov cl, 4 shl bx, cl mov ah, 0 add bx, ax jmp newchar

exit: rethexibin endp

binidec proc near mov cx, 10000d call dec_div mov cx, 1000d call dec_div mov cx, 100d call dec_div mov cx, 10d call dec_div mov cx, 1d call dec_div ret

binidec endp

dec_div proc near mov ax, bx mov dx, 0 div cx mov bx, dx mov dl, al add dl, 30h mov ah, 2 int 21h retdec_div endp

1 a b 5

31 61 62 35

Page 9: 第六章   子程序结构

例:累加数组中的元素(通过存储器传送参数)

data segment ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?data endscode segmentmain proc far assume cs:code,ds:data mov ax, data mov ds, ax

call proadd

mov ax,4c00h int 21hmain endp

code ends end main

proadd proc near push ax push cx push si lea si, ary mov cx, count xor ax, axnext: add ax, [si] add si, 2 loop next mov sum,ax pop si pop cx pop ax retproadd endp

Page 10: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构如果数据段定义如下:

data segment

ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?

ary1 dw 10,20,30,40,50,60,70,80,90,100 count1 dw 10 sum1 dw ?

data ends

如果直接访问内存变量,那么累加数组 ary

和数组 ary1 中的元素不能用同一个子程序 proadd 。

Page 11: 第六章   子程序结构

例:累加数组中的元素(通过地址表传送参数地址)

data segment ary dw 10,20,30,40,50,60,70,80,90,100 count dw 10 sum dw ? table dw 3 dup (?) ; 地址表data endscode segmentmain proc far assume cs:code, ds:data push ds sub ax, ax push ax mov ax, data mov ds, ax mov table, offset ary mov table+2, offset count mov table+4, offset sum mov bx, offset table call proadd retmain endp

Page 12: 第六章   子程序结构

proadd proc near push ax push cx push si push di mov si, [bx] mov di, [bx+2] mov cx, [di] mov di, [bx+4] xor ax, axnext: add ax, [si] add si, 2 loop next mov [di],ax pop di pop si pop cx pop ax retproadd endpcode ends end main

30d 40d 50d 60d 70d 80d 90d100d 10d

ary 20d 10d

countsum

table

0000

0014

0016

0018000000140016

(bx)

(si)

(di)550d

Page 13: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构

例:累加数组中的元素(通过堆栈传送参数地址)

data segment ary dw 10,20,30,40,50,60,70,80,90,100 count dw 10 sum dw ?data ends

stack segment dw 100 dup (?) tos label wordstack ends

Page 14: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构code1 segmentmain proc far assume cs:code1, ds:data, ss:stackstart: mov ax, stack mov ss, ax mov sp, offset tos mov ax, data mov ds, ax

mov bx, offset ary push bx mov bx, offset count push bx mov bx, offset sum push bx

call far ptr proadd mov ax, 4c00h int 21h

main endpcode1 ends

Page 15: 第六章   子程序结构

code2 segment assume cs:code2

proadd proc far

push bp mov bp, sp

push ax push cx push si push di

mov si,[bp+0ah] mov di,[bp+8] mov cx,[di] mov di,[bp+6]

code2 ends end start

xor ax, axnext: add ax, [si] add si, 2 loop next mov [di],ax

pop di pop si pop cx pop ax

pop bp

ret 6

proadd endp

(ip)(cs)sumcountarray

(di) (si) (cx) (ax)

(sp)

(bp) (bp)

(bp)+0ah (bp)+8 (bp)+6

tos

Page 16: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构多个模块之间的参数传送:局部符号:在本模块中定义,在本模块中引用的符号

外部符号:在某一模块中定义,在另一模块中引用的符号

PUBLIC 符号 EXTRN 符号 :类型

extrn proadd : far …… ……code1 segmentstart: …… call far ptr proadd ……code1 ends end start

; proadd1.asm

public proadd …… ……code2 segmentproadd proc far …… retproadd endpcode2 ends end

; proadd2.asm

Page 17: 第六章   子程序结构

例: ; proadd1.asm

extrn proadd : fardata segment common ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?data endscode1 segment main proc far assume cs:code1, ds:datastart: mov ax, data mov ds, ax call far ptr proadd mov ah, 4ch int 21hmain endpcode1 ends end start

Page 18: 第六章   子程序结构

; proadd2.asm

public proadddata segment common ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?data ends code2 segment proadd proc far assume cs:code2,ds:data mov ax, data mov ds, ax push ax push cx push si lea si, ary mov cx, count xor ax, ax

next: add ax, [si] add si, 2 loop next mov sum,ax pop si pop cx pop ax retproadd endpcode2 ends end

Page 19: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构

子程序的嵌套:

主程序 子程序 A 子程序 B

递归子程序: n! = n ( n - 1 ) ( n - 2 ) …1

3! = 3 ×2×1= 6

5. 子程序的嵌套与递归调用

……

call proc_A

……

proc_A

……

call proc_B

……

Call proc_A

ret

proc_B

……

ret

Page 20: 第六章   子程序结构

例:计算 n!

frame struc save_bp dw ? save_cs_ip dw 2 dup(?) n dw ? result_addr dw ?frame ends;---------------------------------data segment n_v dw 3 result dw ?data ends;---------------------------------stack segment dw 128 dup (?) tos label wordstack ends

mov ax, [bp] . n

mov bx, [bp] .result_addr

0!=1

n!=n(n-1)!

Page 21: 第六章   子程序结构

code segmentmain proc far assume cs:code, ds:data, ss:stackstart: mov ax, stack ;用户堆栈地址 mov ss, ax mov sp, offset tos push ds ;保存返回 DOS 地址 sub ax, ax push ax mov ax, data ;数据段地址 mov ds, ax mov bx, offset result ; 结构数据入栈 push bx mov bx, n_v push bx call far ptr fact retmain endpcode ends

Page 22: 第六章   子程序结构

code1 segment assume cs:code1fact proc far push bp mov bp, sp push bx push ax mov bx, [bp].result_addr mov ax, [bp].n cmp ax, 0 je done push bx dec ax push ax call far ptr fact mov bx, [bp].result_addr mov ax, [bx] mul [bp].n jmp short returndone: mov ax,1return: mov [bx], ax pop ax pop bx pop bp ret 4fact endpcode1 ends

(AX) (BX) (BP)CODE中的 (IP)CODE中的 (CS) 3RESULT的地址

第 1帧

(AX) (BX) (BP)CODE1中的 (IP)CODE1中的 (CS) 2RESULT的地址

第 2帧

(AX) (BX) (BP)CODE1中的 (IP)CODE1中的 (CS) 1RESULT的地址

第 3帧

(AX) (BX) (BP)CODE1中的 (IP)CODE1中的 (CS) 0RESULT的地址

第 4帧

00FA

00F2

00E4

00D6

00C8

0000

00F2

00E4

00D6

Page 23: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构 fact proc near push ax push bp mov bp, sp mov ax, [bp+6] cmp ax, 0 jne fact1 inc ax jmp exitfact1: dec ax push ax call fact pop ax mul word ptr[bp+6]exit: mov [bp+6], ax pop bp pop ax ret fact endp

例:计算 n!

mov bx, n_vpush bxcall factpop result

主程序:

(BP)(AX)(IP) 0(BP)(AX)(IP) 1(BP)(AX)(IP) 2(BP)(AX)(IP) 3

Page 24: 第六章   子程序结构

例:将字符串反序输出revers proc near push ax push bx push dx push bp mov bp,sp mov bx,[bp+10] mov al,[bx] cmp al,'$' jne re_call jmp returnre_call: inc bx push bx call revers pop bx mov dl,[bx] mov ah,2 int 21hreturn: pop bp pop dx pop bx pop ax retrevers endp

mov bx, offset strpush bxcall reverspop bxmov dl, [bx]mov ah, 2int 21h

主程序:

str db ‘happy!’,’$’

(bp)

( bp )( dx )( bx )( ax )返址h的地址

第 1帧

Page 25: 第六章   子程序结构

汇编语言程序设计

第六章 子程序结构

第六章作业

Page 240 6.3 6.4

6.7 6.8