第 6 章 子程序结构

42
22/1/15 ch6 1 安安安安安安 安安安安安安安安安 安安安 安安安安安 《》 安6安 安安安安安安 安安安安安安 安 ,一 安安安安安安安安安安安安安 安安安 安安安安安安安 安安安安安安安安安安安安安安安安 。一 安安安安安安 安安安安安安安安安 安安安安安安安安安 安安安安安安 ,。 , 安安安安安安 安安安安安安 安安安安安安安安安安安安安安安安安安 安安安安安安安安安安安安安安安安安安安6安 安安安安安

Upload: audrey-cunningham

Post on 31-Dec-2015

136 views

Category:

Documents


6 download

DESCRIPTION

第 6 章 子程序结构. 在程序设计中,我们会发现一些 多次无规律重复的程序段或语句序列 。解决此类问题一个行之有效的方法就是将它们设计成 可供反复调用的独立的子程序结构 ,以便在需要时调用。在汇编语言中 , 子程序又称过程 。 调用子程序的程序称为主调程序或主程序 。. 子程序的结构. 子程序的基本结构包括以下几个部分: ( 1 )子程序定义 ( 2 )保护现场和恢复现场 ( 3 )子程序体 ( 4 )子程序返回. 6.1 子程序的设计方法. 6.1.1 子程序的定义. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第 6 章       子程序结构

23/4/19 ch6 1

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

在程序设计中,我们会发现一些多次无规律重复的程序段或语句序列。解决此类问题一个行之有效的方法就是将它们设计成可供反复调用的独立的子程序结构,以便在需要时调用。在汇编语言中 , 子程序又称过程子程序又称过程。

调用子程序的程序称为主调程序或主程序调用子程序的程序称为主调程序或主程序。

第 6 章 子程序结构

Page 2: 第 6 章       子程序结构

23/4/19 ch6 2

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

子程序的基本结构包括以下几个部分:

(( 11 )子程序定义 )子程序定义 (( 22 )保护现场和恢复现场 )保护现场和恢复现场 (( 33 )子程序体 )子程序体 (( 44 )子程序返回 )子程序返回

子程序的结构

Page 3: 第 6 章       子程序结构

23/4/19 ch6 3

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

子程序的定义是由过程定义伪指令 PROC 和 ENDP 来完成的。其格式如下:过程名 过程名 PROC [NEAR/FAR]PROC [NEAR/FAR] ┆ ┆过程名 过程名 ENDPENDP 其中其中 PROCPROC 表示过程定义开始,表示过程定义开始, ENDPENDP 表示过程表示过程定义结束。定义结束。过程名是过程入口地址的符号表示过程名是过程入口地址的符号表示。。 一般过程名同标号一样,具有三种属性,即段属一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性(性、偏移地址属性以及类型属性( NEAR NEAR 和 和 FAR)FAR) 。

6.1.1 6.1.1 子程序的定义子程序的定义6.1 子程序的设计方法

Page 4: 第 6 章       子程序结构

23/4/19 ch6 4

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

如果调用程序和过程在同一代码段同一代码段中,则使用 NEARNEAR 属性属性;

MAIN PROC FARMAIN PROC FAR … CALL SUBR1CALL SUBR1 RETMAIN ENDPMAIN ENDP;SUBR1 PROC SUBR1 PROC NEARNEAR … RETSUBR1 ENDPSUBR1 ENDP

MAIN PROC FARMAIN PROC FAR … CALL SUBR1CALL SUBR1 RET

SUBR1 PROC SUBR1 PROC NEARNEAR … RETSUBR1 ENDPSUBR1 ENDPMAIN ENDPMAIN ENDP

6.1.2 子程序的调用和返回

Page 5: 第 6 章       子程序结构

23/4/19 ch6 5

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

如果调用程序和过程不在同一代码段中调用程序和过程不在同一代码段中,则使用 FAR 属性;

SEGX SEGMENT …SUBT PROC FARFAR … RETSUBT ENDP … CALL SUBT …SEGX ENDS;

SEGY SEGMENTSEGY SEGMENT … CALL SUBT …SEGY ENDS

Page 6: 第 6 章       子程序结构

23/4/19 ch6 6

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

6.1.3 保护现场和恢复现场例如:若子程序例如:若子程序 PROGPROG 中改变了寄存器中改变了寄存器 AXAX ,, BXBX ,, CXCX ,, DXDX 的值,的值,

则则

可采用如下方法保护和恢复现场。可采用如下方法保护和恢复现场。PROG PROC

PUSHPUSH AXAX

PUSH PUSH BX BX

PUSHPUSH CXCX ;保护现场;保护现场PUSHPUSH DXDX

• ┆ POPPOP DXDX

POPPOP CXCX

POPPOP BXBX ;恢复现场;恢复现场POPPOP AXAX

RET ;返回断点处PROC ENDP

Page 7: 第 6 章       子程序结构

23/4/19 ch6 7

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

6.1.4 主程序与子程序参数传递方式 1 1 通过寄存器传送参数通过寄存器传送参数

这是最常用的一种方式,使用方便,但参数很多时不能使用这种方法。

例:十进制到十六进制转换的程序。程序要求从键盘取得一个十进制数,然后把该数以十六进制的形式在屏幕上显示出来。 开始

调用 DECIBIN

调用 CRLF

调用 BINIHEX

调用 CRLF

结束

从键盘取得十进制数,保存到 BX中

显示回车和换行

用十六进制形式显示 BX中的数

Page 8: 第 6 章       子程序结构

23/4/19 ch6 8

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

Decihex segment assume cs:Decihex

Main proc farMain proc far

Repeat: push dsRepeat: push ds

xor ax, axxor ax, ax

push axpush ax

call decibincall decibin

call crlfcall crlf

call binihexcall binihex

call crlfcall crlf

retret

Main endpMain endp

Decibin proc nearDecibin proc near mov bx, 0Newchar: mov ah, 1 int 21h sub al, 30h jl exit cmp al, 9 jg exit cbw xchg ax, bxxchg ax, bx mov cx, 10mov cx, 10 mul cxmul cx xchg ax, bx xchg ax, bx ; 每次乘的 add bx, ax add bx, ax ; 结果在 BX 中 jmp newchar Exit : retDecibin endp Decibin endp

Page 9: 第 6 章       子程序结构

23/4/19 ch6 9

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

Binihex proc nearBinihex proc near mov ch, 4mov ch, 4

Rotate: mov cl, 4 Rotate: mov cl, 4

rol bx, clrol bx, cl

mov dl, blmov dl, bl

and dl, 0fhand dl, 0fh

add dl, 30hadd dl, 30h

cmp dl, 3ahcmp dl, 3ah

jl printjl print

add dl, 7hadd dl, 7h

Print: mov ah, 2Print: mov ah, 2

int 21hint 21h

dec chdec ch

jnz rotatejnz rotate

ret ret

Binihex endpBinihex endp

Crlf proc nearCrlf proc near

mov ah, 2mov ah, 2

mov dl, odhmov dl, odh

int 21hint 21h

mov dl, oahmov dl, oah

int 21hint 21h

retret

Crlf endpCrlf endp

Decihex ends end repeat

Page 10: 第 6 章       子程序结构

23/4/19 ch6 10

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

22 如果过程和调用过程在同一源文件(同一模块)中,如果过程和调用过程在同一源文件(同一模块)中,则过程可直接访问模块中的变量。则过程可直接访问模块中的变量。

例 例 6.4 6.4 主程序主程序 MAINMAIN 和过程和过程 PROADDPROADD 在同一源文件在同一源文件中,要求用过程中,要求用过程 PROADDPROADD 累加数组的所有元素,并累加数组的所有元素,并把和(不考虑溢出的可能性)送到指定的存储单元把和(不考虑溢出的可能性)送到指定的存储单元中去中去

Page 11: 第 6 章       子程序结构

23/4/19 ch6 11

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

DATA SEGMENTDATA SEGMENT

ARY ARY DW 100 DUP (?) DW 100 DUP (?)

COUNTCOUNT DW 100 DW 100

SUM SUM DW ? DW ?

DATA ENDSDATA ENDS

CODE SEGMENTCODE SEGMENT MAIN PROC FARMAIN PROC FAR

ASSUME CS:CODE , DS:DATAASSUME CS:CODE , DS:DATA

START: PUSH DSSTART: PUSH DS

SUB AX ,AXSUB AX ,AX

PUSH AX PUSH AX

MOV AX , DATAMOV AX , DATA

… …

CALL NEAR PTR PROADDCALL NEAR PTR PROADD

… …

RETRET

MAIN ENDPMAIN ENDP

PROADD PROC NEARPROADD PROC NEAR

PUSH AXPUSH AX

PUSH CXPUSH CX

PUSH SIPUSH SI

PUSH DIPUSH DI

LEA SI ,LEA SI ,ARYARY

MOV CX ,MOV CX ,COUNTCOUNT

XOR AX , AXXOR AX , AX

NEXT: ADD AX , [SI]NEXT: ADD AX , [SI]

ADD SI , 2ADD SI , 2

LOOP NEXTLOOP NEXT

MOV MOV SUMSUM , AX , AX

POP DIPOP DI

POP SIPOP SI

POP CXPOP CX

POP AXPOP AX

RETRET

PROADD ENDPPROADD ENDP

CODE ENDSCODE ENDS END STARTEND START

Page 12: 第 6 章       子程序结构

23/4/19 ch6 12

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

CODE SEGMENT

ARY DW 100 DUP(?)ARY DW 100 DUP(?)

COUNT DW 100COUNT DW 100

SUM DW ?SUM DW ?

NUM DW 100 DUP (?)NUM DW 100 DUP (?)

N DW 100N DW 100

TOTAL DW ?TOTAL DW ?

;;

MOV TABLE , OFFSET ARYMOV TABLE , OFFSET ARY

MOV TABLE+2, OFFSET COUNTMOV TABLE+2, OFFSET COUNT

MOV TABLE+4 , OFFSET SUNMOV TABLE+4 , OFFSET SUN

MOV BX , OFFSET TABLEMOV BX , OFFSET TABLE

CALL PROADD CALL PROADD ;计算;计算 SUMSUM

PROADD PROC NEAR PUSH AX PUSH CX PUSH SI MOV SI , MOV SI ,

MOV CX , MOV CX ,

MOV DI , MOV DI ,

XOR AX , AXXOR AX , AX

NEXT: ADD AX , [SI]NEXT: ADD AX , [SI]

ADD SI , 2ADD SI , 2

LOOP NEXTLOOP NEXT

MOV , AXMOV , AX POP SI POP CX POP AX RETPROADD ENDPCODE ENDS END START

[BX][BX+2]

[BX+4]

[DI]

3 通过地址表传递参数

Page 13: 第 6 章       子程序结构

23/4/19 ch6 13

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

例:把内存中字变量例:把内存中字变量 numnum 的的值,转换为值,转换为 44 个用个用 ASCⅡASCⅡ 码码表示的表示的 1616 进制数码,串的起进制数码,串的起始地址为始地址为 stringstring 。。

Data segmentNum dw 25afhString db 4 dup(?), ‘$’, 0dh, 0ahData endsStack segment para stack ‘stack’ db 100 dup(?)Stack endsCode segment assume cs:code, ds:data, ss:stackMain proc farBegin: push ds xor ax, ax push ax mov ax,data mov ds, ax lea bx, string lea bx, string push bxbx push num call binhexcall binhex lea dx, string mov ah, 9 int 21h retMain endp

2000:0000

2000:0002·

3000:0000

3000:0001

3000:0003

3000:0004

3000:0007

3000:0009

3000:000d

3000:000e

3000:0012

3000:0015

3000:0019

15150000af250200

sp

string 地址

Num

Lea dx,string地址( IP )

4 通过堆栈传递地址或参数

Page 14: 第 6 章       子程序结构

23/4/19 ch6 14

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章Binhex proc nearBinhex proc near push bp mov bp,sp push ax push di push bx push cx pushf mov ax, [bp+4] ; ax=25afh mov di, [bp+6] ; di=0002 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

0015001525af0002

sp

string 地址Num

Lea dx,string 地址 (IP)

flagcxbxdiaxbp(Sp→)bp

bp+2bp+4bp+6

Bp-6Bp-4Bp-2

Page 15: 第 6 章       子程序结构

23/4/19 ch6 15

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章Next: mov [di], bl inc di dec ch jnz rota popf pop cx pop bx pop di pop ax pop bp ret 4ret 4Binhex endpBinhex endp

Code ends end begin

0015001525af0002

sp

string 地址Num

Lea dx,string 地址 (IP)

flagcxbxdiaxbp

sp

Page 16: 第 6 章       子程序结构

23/4/19 ch6 16

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

例例 33 :求:求 1010 个数的累加值个数的累加值 . . ---------------- 远调用远调用Data segmentAry db 10 dup(?)Count db 10Sum db ?Data endsStack segment para stack ‘stack’ db 100 dup(?)Stack endsCode1 segment assume cs:code1, ds:data, ss;stackMain proc farStart: push ds xor ax, ax push ax mov ax, data mov ds, ax

Page 17: 第 6 章       子程序结构

23/4/19 ch6 17

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

Mov bx, offset ary Push bx Mov bx, offset count Push bx Mov bx, offset sum Push bx Call far ptr proadd mov al, summov al, sum mov dl, al mov ah, 2 int 21h retMain endpCode1 ends

Sum 地址

Count 地址

Ary 地址

MOV AL, SUM MOV AL, SUM 地址地址sp IP

CS

Page 18: 第 6 章       子程序结构

23/4/19 ch6 18

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

Sum 地址

Count 地址

Ary 地址

sp

MOV AL, SUM 地址

disicxaxbp(Sp→)bpIPCS

Code2 segment assume cs:code2Proadd proc farProadd proc far push bp mov bp, sp push ax push cx push si push di mov si, [bp+0ah] mov di, [bp+08h] mov cl, [di] mov di, [bp+06h] xor al, alAgain: add al, [si] inc si dec cl jnz again mov [di], al pop di pop si pop cx

pop ax pop bp ret 6ret 6Proadd endpCode2 ends end start

[bp+0ah]

[bp+08h]

[bp+06h]

Page 19: 第 6 章       子程序结构

23/4/19 ch6 19

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

(1) PUBLIC 伪指令 格式: PUBLIC PUBLIC 符号 符号 [[ ,符号,符号 ]] 功能:说明其后的符号是全局符号。全局符号能被其他模块引用。 ( 局部符号)

(2) EXTRN 伪指令 格式: EXTRN EXTRN 符号:类型 符号:类型 [[ ,符号:类型,符号:类型 ]] 功能:说明在本模块中需要引用的、由其他模块定义的符号,即外部符号。

5 5 多个模块之间的参数传送问题多个模块之间的参数传送问题

Page 20: 第 6 章       子程序结构

23/4/19 ch6 20

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章source module 1source module 1

extrn a:wordextrn a:word

Data1 segmentData1 segment

b dw ?b dw ?

Data1 endsData1 ends

code1 segmentcode1 segment

assume cs:code1,ds:data1assume cs:code1,ds:data1

Main proc farMain proc far

start: mov ax , data1start: mov ax , data1

mov ds,axmov ds,ax

……

mov ah,4chmov ah,4ch

int 21hint 21h

Main endpMain endp

Code1 ends Code1 ends

End startEnd start

source module 2source module 2

public apublic a

Data2 segmentData2 segment

a dw ?a dw ?

Data2 endsData2 ends

code2 segmentcode2 segment

assume cs:code2,ds:data2assume cs:code2,ds:data2

Main proc farMain proc far

start: mov ax , data2start: mov ax , data2

mov ds,axmov ds,ax

……

mov ah,4chmov ah,4ch

int 21hint 21h

Main endpMain endp

Code2 ends Code2 ends

End startEnd start

注意:应先有应先有 public public 定义,然后才有定义,然后才有 extrnextrn 说说明明

Page 21: 第 6 章       子程序结构

23/4/19 ch6 21

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

NAME MOD1

EXTRNEXTRN DISPDISP :: FARFAR

PUBLICPUBLIC STR1STR1 ,, N N ,, BUFBUF

DATA1 SEGMENT

STR1 DB ‘HOW DO YOU DO?’

N = $-STR1

BUF DB ‘THIS IS AN EXAMPLE OF MODULES PROGRAM $′DATA ENDS

STACK SEGMENT STACK

DB 200 DUP ( 0 )STACK ENDS

CODE1 SEGMENT

ASSUME CS : CODE1 , DS : DATA1 , SS : STACK

START : MOV AX , DATA

MOV DS , AX

CALLCALL DISPDISP

MOV AH , 4CH

INT 21H

CODE1 ENDS

END START

例:用模块化程序设计方法建立两个模块 MOD1 ASM 和 MOD2 ASM 的数据通讯。

Page 22: 第 6 章       子程序结构

23/4/19 ch6 22

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

NAME MOD2

EXTRNEXTRN STR1STR1 :: BYTEBYTE ,, STR2STR2 :: BYTEBYTE ,, NN ::ABSABS

PUBCICPUBCIC DISPDISP

DATA2 SEGMENT

STR2 DB 81 DUP ( 0 )DATA2 ENDS

CODE2 SEGMENT

ASSUME CS : CODE2 , ES :DATA2

DISPDISP PROCPROC FARFAR

MOV AX , DATA2

MOV ES , AX

LEALEA BXBX ,, STR1STR1

MOV CX , N

LEA SI , STR2

NEXT : MOV AL , [BX]

MOV ES : [SI] , AL

INC BX

INC SI

LOOP NEXT

LEA DX , BUF

MOV AH , 9

INT 21H

RET

DISPDISP ENDPENDP

CODE2 ENDS

END

Page 23: 第 6 章       子程序结构

23/4/19 ch6 23

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

6.1.5 增强功能的过程定义伪操作Procname PROC Procname PROC [attributes field] [[attributes field] [USERUSER register list] register list]

[,parameter field][,parameter field]

Procname ENDPProcname ENDP

Attributes field(Attributes field( 属性字段)属性字段)包括:

DistanceDistance : near near 、、 farfar

Language typeLanguage type : 说明是那种高级语言的子程序 如 pascal pascal 、、 cc 等。

VisibilityVisibility : 说明程序的可见性 是 privateprivate 或是 publicpublic 。

ProloguePrologue : 是一个宏的名字宏的名字,允许用宏来控制过程的入口或出口有关的代码

USERUSER :该字段用来指定用户所需保存和恢复的寄存器表指定用户所需保存和恢复的寄存器表。

Parameter fieldParameter field: 参数字段 ,允许用户指定该过程所用的参数允许用户指定该过程所用的参数 。

标识符:类型标识符:类型 [[ ,标识符:类型,标识符:类型 ]]

Page 24: 第 6 章       子程序结构

23/4/19 ch6 24

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

Data segmentAry db 10 dup(?)Count db 10Sum db ?Data endsStack segment para stack ‘stack’ db 100 dup(?)Stack endsCode1 segment assume cs:code1, ds:data, ss:stackMain proc farStart: push ds xor ax, ax push ax 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 proaddCall far ptr proadd mov al, sum mov dl, al mov ah, 2 int 21h retMain endpCode1 ends

例 6 .4 用增强功能过程定义伪操作实现

Page 25: 第 6 章       子程序结构

23/4/19 ch6 25

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章Code2 segment assume cs:code2Proadd proc farProadd proc far push bp mov bp, sp push ax push cx push si push di mov si, [bp+0ah] mov di, [bp+08h] mov cl, [di] mov di, [bp+06h] xor al, alAgain: add al, [si] inc si dec cl jnz again mov [di], al pop di pop si pop cx pop ax pop bp ret 6ret 6Proadd endpCode2 ends end start

Code2 segment assume cs:code2Proadd procProadd proc pascalpascal useruser ax cx si diax cx si di , parapara:wordword,parcparc:wordword,parspars:wordword mov si, para mov di, parc mov cl, [di] mov di, pars xor al, alAgain: add al, [si] inc si dec cl jnz again mov [di], al ret ret Proadd endpCode2 ends end start

SumSum 地址地址

CountCount 地址地址

AryAry 地址地址

(bp)IPCS

( bp +2)( bp +4)( bp +6)( bp +8)( bpbp + +aa)

原始 bp

mov al, sum

parapara

parsparsparcparc

局部局部变量变量

disicxax

( bp -2)

Page 26: 第 6 章       子程序结构

23/4/19 ch6 26

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

增强功能的过程定义伪操作除了以上功能外 ,还可以在还可以在过程中定义局部变量过程中定义局部变量。局部变量是在过程内部使用的变量,局部变量是在过程内部使用的变量,他是在过程调用是在堆栈中建立的,在退出过程是被释放他是在过程调用是在堆栈中建立的,在退出过程是被释放。

可以用 LOCAL 定义

LOCAL LOCAL 变量:类型变量:类型 [[ ,变量:类型,变量:类型 ]]

Sum 地址

Count 地址

Ary 地址

(bp)IPCS

( bp +2)( bp +4)( bp +6)( bp +8)( bp +a)

原始 bp( bp -2)( bp -4) 局部局部

变量变量

Page 27: 第 6 章       子程序结构

23/4/19 ch6 27

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

6.2 子程序的嵌套 一个子程序可以作为调用程序去掉用另一个子程序,这种一个子程序可以作为调用程序去掉用另一个子程序,这种情况称为子程序的嵌套情况称为子程序的嵌套。嵌套深度不限。但应注意什么问题?

堆栈溢出:上溢、下溢

递归子程序:如果一个子程序调用的是子程序的本身,就是递 归子程序。

Page 28: 第 6 章       子程序结构

23/4/19 ch6 28

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

例例 5: 5: 计算 计算 N!=N*(N-1)*(N-2)* ……*1N!=N*(N-1)*(N-2)* ……*1 ---------------- 递归子程序递归子程序Data segmentNum db 3Result dw ?Data endsStack segment para stack ‘stack’ db 100 dup(?)Stack endsCode segment assume cs:code, ds:data, ss:stack

Main proc farMain proc farBegin: push ds xor ax, ax push ax mov ax, data mov ds, ax

Page 29: 第 6 章       子程序结构

23/4/19 ch6 29

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

mov ah, 0 mov al, num call factorcall factor mov result, ax ret

Main endpMain endp

Factor procFactor proc push ax sub ax, 1 jne f_cont pop ax jmp returnf_cont: call factorcall factor pop cx mul clreturn: retfactor endpfactor endpCode ends end begin

IP1 Mov result, ax 地址

3

IP2Pop cx 地址

2

IP3 Pop cx 地址1ax =1

IP POP CX 地址cx =2ax*cx =1*2

IP POP CX 地址cx =3ax*cx =1*2*3

IP Mov result, ax 地址

Page 30: 第 6 章       子程序结构

23/4/19 ch6 30

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

常用的 DOS 系统功能调用

• 1.单字符输入( 1 号调用)• 2.单字符显示( 2 号调用)• 3 .打印输出( 5 号调用)• 4.结束调用( 4CH 号调用)• 5.显示字符串( 9 号调用)• 6.字符串输入( 10 号调用)

Page 31: 第 6 章       子程序结构

23/4/19 ch6 31

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

•1.单字符输入( 1 号调用)格式: MOV AH , 1

  INT 21H

功能:从键盘输入字符的 ASCII 码送入寄存器 AL 中,并送显示器显示。

• 2.单字符显示( 2 号调用)格式: MOV DL ,待显示字符的 ASCII 码  MOV AH , 2

  INT 21H

功能:将 DL 寄存器中的字符送显示器显示 .

Page 32: 第 6 章       子程序结构

23/4/19 ch6 32

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

• 3.打印输出( 5 号调用)格式: MOV DL ,待打印字符的 ASCII 码  MOV AH , 5  INT 21H• 功能:将 DL 寄存器中的字符送打印机打印。

• 4.结束调用( 4CH 号调用)格式: MOV AH , 4CH  INT 21H功能:终止当前程序并返回调用程序。

Page 33: 第 6 章       子程序结构

23/4/19 ch6 33

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章• 5.显示字符串( 9 号调用)格式: LEA DX ,待显示字符串首偏移地址  MOV AH , 9  INT 21H功能:将当前数据区中以‘$’结尾的字符串送显示器显示。

• 6.字符串输入( 10 号调用)格式: LEA DX ,缓冲区首偏移地址 MOV AH , 10 INT 21H功能:从键盘上输入一字符串到用户定义的输入缓冲区中,并送显示器显示。

maxlen db 32 actlen db ? string db 32 dup(?) lea dx , maxlen mov ah,0ah int 21h

说明:缓冲区的第一个字节保存最大字符数,这个最 大字符数由用户程序给出。如果键入的字符数 比此数大,机器发出嘟嘟声。第二个字节存放 实际输入的字节数,这个不是由用户填入的而 由功能 A 填入的。在这两个字节之后,才是我们 输入的字符串。

Page 34: 第 6 章       子程序结构

23/4/19 ch6 34

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

6.3 子程序举例例 1 : HEXIDEX 是一个十六进制数转换成十进制数的程序。要求把从键盘输入的 0 — FFFFH 的十六进制正数转换为十进制数并在屏幕上显示出来。

Display equ 2h

Key equ 1h

Doscall equ 21h

Hexidec segment

Main proc far

assume cs:hexidec

Start:

push ds

sub ax,ax

push ax

call hexidec

call crlf

call binidec

call crlf

jmp main

ret

main endp

Crlf proc near

mov dl ,0ah

mov ah,display

int boscall

mov dl,0dh

mov ah,display

int doscall

ret

crlf endp

Hexidec ends

end start

Page 35: 第 6 章       子程序结构

23/4/19 ch6 35

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章Hexidec proc nearHexidec proc near

mov bx ,0mov bx ,0

Newchar: mov key_inNewchar: mov key_in

int doscallint doscall

sub al,30hsub al,30h

jl exitjl exit

cmp al, 10dcmp al, 10d

jl add_tojl add_to

sub al ,27hsub al ,27h

cmp al,0ahcmp al,0ah

jl exitjl exit

cmp ah,10hcmp ah,10h

jge exitjge exit

Add_to: mov cl ,4Add_to: mov cl ,4

shl bx , clshl bx , cl

mov ah ,0mov ah ,0

add bx,axadd bx,ax

jmpjmp

Exit:Exit:

RetRet

Hexidec endpHexidec endp

Binidec proc nearBinidec proc near

mov cx , 10000dmov cx , 10000d

call dec_divcall dec_div

mov cx , 1000dmov cx , 1000d

call dec_divcall dec_div

mov cx,100dmov cx,100d

call dec_divcall dec_div

mov cx,10dmov cx,10d

call dec_divcall dec_div

mov cx,1dmov cx,1d

call dec_divcall dec_div

retret

Dec_div proc nearDec_div proc near

mov ax, bxmov ax, bx

mov dx ,0mov dx ,0

div cxdiv cx

mov bx,dxmov bx,dx

mov dl,almov dl,al

add dl,30h add dl,30h

mov ah,displaymov ah,display

int doscallint doscall

ret

dec_div endp

Binidec endp

Page 36: 第 6 章       子程序结构

23/4/19 ch6 36

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

例 2 :一个简单的信息检索系统。在数据区里,有 10 个不同的信息,编号为 0—9 ,每个信息包括 30 个字符。现在要编制一个程序:从键盘接收 0—9 之间的一个编号,然后在屏幕上显示相应编号的信息的内容。Datarea segment

thirty db 30

msg0 db ‘ 0 I like my IBM-PC--------------’

msg1 db ‘ 1 I like my IBM-PC--------------’

msg2 db ‘ 2 I like my IBM-PC--------------’

msg3 db ‘ 3 I like my IBM-PC--------------’

msg4 db ‘ 4 I like my IBM-PC--------------’

msg5 db ‘ 5 I like my IBM-PC--------------’

msg6 db ‘ 6 I like my IBM-PC--------------’

msg7 db ‘ 7 I like my IBM-PC--------------’

msg8 db ‘ 8 I like my IBM-PC--------------’

msg9 db ‘ 9 I like my IBM-PC--------------’

errmsg db ‘error!!! Invalid praameter’

Datarea ends

Page 37: 第 6 章       子程序结构

23/4/19 ch6 37

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

Stack segment

db 256 dup(0)

tos lable word

Stack ends

Prognam segment

assume cs:prognam ,ds:datarea,ss:stack

Start: push ds

xor ax,ax

push ax

mov ax,stack

mov ss,ax

mov ax,datarea

mov ds,ax

mov sp,offset tos

Begin:mov ah,1

int 21h

sub al,’0’

jc error

cmp al, ‘9’

ja error

Mov bx,offset msg0

Mul thirty

Add bx,ax

Call display

Jmp begin

Error: mov bx,offset errmsg

call display

ret

Display proc near

mov cx,30

mov dl,[bx]

call dispchar

inc bx

loop disp1

mov dl,0dh

call dispchar

mov dl,0ah

call dispchar

ret

Dispchar endp

Dispchar proc naer

mov ah,2

int 21h

ret

Dispchar endp

Main endp

Prognam ends

End start

Page 38: 第 6 章       子程序结构

23/4/19 ch6 38

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

例 3 :人名排序程序。先从终端键入最多 30个人名,当所有人名都进入后,按字母上升的次序将人名排序,并在屏幕上显示已经排好的人名。

Page 39: 第 6 章       子程序结构

23/4/19 ch6 39

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章Data segment

namepar label byte

maxnlen db 21

namelen db ?

namefld db 21 dup(?)

crlf db 13,10,’$’

endaddr dw ?

messg1 db ‘name?’,’$”

messg2 db ‘sorted names’,13,10,’$’

namectr db 0

nametab db 30 dup (20 dup(‘ ’))

namesav db 20 dup (?),13,10,’$’

swapped db 0

Data ends

Code segment

main proc far

assume cs:code,ds:data,es:data

start:push ds

mov ax,0

push ax

mov ax,data

mov ds,ax

mov es,ax

cld

lea di,nametab

a20loop:call b10read

cmp namelen,0

jz a30

cmp namectr,30

je a30

call d10stor

jmp a20loop

a30:cmp namectr,1

jbe a40

call g10sort

call k10disp a40:mov ah,4ch

Int 21h

Main endp

Page 40: 第 6 章       子程序结构

23/4/19 ch6 40

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章 b10read proc nearb10read proc near

mov ah,09mov ah,09

lea dx ,messg1lea dx ,messg1

int 21hint 21h

mov ah,0ahmov ah,0ah

lea dx,nameparlea dx,namepar

int 21hint 21h

mov ah,09hmov ah,09h

lea dx crlflea dx crlf

Int 21hInt 21h

mov bx,0mov bx,0

mov bl ,namelenmov bl ,namelen

mov cx,21mov cx,21

sub cx,bxsub cx,bx

b20: mov namefld[bx],20hb20: mov namefld[bx],20h

inc bxinc bx

loop b20loop b20

retret

b10read endpb10read endp

d10stor proc neard10stor proc near

inc namectrinc namectr

cldcld

lea si , namectrlea si , namectr

mov cx,10mov cx,10

rep movswrep movsw

retret

p10stor endpp10stor endp

g10sort proc nearg10sort proc near

sub di ,40sub di ,40

mov endaddr,dimov endaddr,di

g20: mov swapped,0g20: mov swapped,0

lea si,nametablea si,nametab

g30: mov cx,20g30: mov cx,20

mov di,simov di,si

add di,20add di,20

add ax,diadd ax,di

mov ax,dimov ax,di

mov bx,simov bx,si

repe cmpsbrepe cmpsb

jbe g40jbe g40

call h10xchgcall h10xchg

g40: mov si,axg40: mov si,ax

cmp swapped,cmp swapped,00

jnz g20jnz g20

retret

G10sort endpG10sort endp

Page 41: 第 6 章       子程序结构

23/4/19 ch6 41

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

h10xchg proc near

mov cx,10

lea di , namesav

mov si,bx

rep movsw

mov cx,10

mov di,bx

rep movsw

mov cx ,10

lea si,namesav

rep movsw

mov swapped,1

ret

h10xchg endp

k10disp proc near

mov ah,09

lea dx,messg2

int 21h

lea si,nametab

lea di,namesav

mov cx,10

rep movsw

mov ah,09

lea dx, namesav

int 21h

dec namectr

jnz k20

ret

K10disp endp

end start

Page 42: 第 6 章       子程序结构

23/4/19 ch6 42

安徽理工大学 计算机科学与技术系 李敬兆 《汇编语言》 第 6章

第六章 作业

6.1

6.2

6.3

6.7