文档库 最新最全的文档下载
当前位置:文档库 › 汇编语言课件6

汇编语言课件6

汇编语言课件6
汇编语言课件6

第六章子程序结构6.1 子程序的设计方法

过程(子程序)定义伪操作

procedure_name PROC NEAR ( FAR )

……

procedure_name ENDP

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

(段内调用)

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

(段间调用)

保存与恢复寄存器

subt proc far

push ax

push bx

push cx

push dx

......

pop dx

pop cx

pop bx

pop ax

ret

subt endp

子程序的调用和返回

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

(1) 保存返回地址

(2) 转子程序

(IP) ←subp的偏移地址

call far ptr subp

(1) 保存返回地址

(2) 转子程序

(CS) ←subp的段地址

(IP) ←subp的偏移地址

子程序的变量传送

(1)通过寄存器传送变量

(2)通过存储器传送变量

*子程序和调用程序在同一程序模块中,则子程序可

直接访问模块中的变量。

*子程序和调用程序不在同一程序模块中,则有两种

传送方式:建立公共数据区和使用外部符号。

(3)通过地址表传送变量地址

(4)通过堆栈传送变量或变量地址

例6.3 十进制到十六进制的转换程序(通过寄存器传送变量)decihex segment ; 10 16

assume cs: decihex

main proc far

push ds

sub ax, ax

push ax

repeat: call decibin; 10→2

call crlf

call binihex; 2→16

call crlf

jmp repeat

ret

main endp

decibin proc near ; 10→2

mov bx, 0

newchar: mov ah, 1

int 21h

sub al, 30h

jl exit ; <0退出

cmp al, 9d

jg exit ; >9退出

cbw

xchg ax, bx

mov cx, 10d

mul cx

xchg ax, bx

add bx, ax

jmp newchar

exit: ret

decibin endp

binihex proc near ; 2→16

mov ch, 4

rotate: mov cl, 4

rol bx, cl

mov al, bl

and al, 0fh

add al, 30h

cmp al, 3ah

jl printit

add al, 7h ; ‘A’~’F’ printit: mov dl, al

mov ah, 2

int 21h

dec ch

jnz rotate

ret

binihex endp

crlf proc near

mov dl, 0dh

mov ah, 2

int 21h

mov dl, 0ah

mov ah, 2

int 21h

ret

crlf endp

decihex ends

end main

例6.4 累加数组中的元素(直接访问变量)data segment

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

count dw 10

sum dw ?

data ends

code segment

main proc far

assume cs:code, ds:data

start:

push ds

sub ax, ax

push ax

mov ax, data

mov ds, ax

call near ptr proadd

ret

main endp

proadd proc near

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

ret

proadd endp

code ends

end start

如果数据段定义如下:

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

例6.4 累加数组中的元素(通过堆栈传送变量地址)

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 word

stack ends

code1 segment

main proc far

assume cs:code1, ds:data, ss:stack

start:

mov ax, stack

mov ss, ax

mov sp, offset tos

push ds

sub 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 proadd

ret

main endp

code1 ends

结构预置语句:把结构中各字段的数据存入存储器,

并可重新输入字符串和数值。

格式:变量名结构名< >

变量名结构名<预赋值说明>

例:S991000 STUDENT_DAT A < >

S991001 STUDENT_DAT A <, 1001, 22, >

STUDENT STUDENT_DATA 100 DUP (< >) 访问结构数据变量:

MOV AL, https://www.wendangku.net/doc/6b16336922.html,[SI]

MOV AL, [BX].NAME[SI]

MOV AL, STUDENT+4*https://www.wendangku.net/doc/6b16336922.html,[SI]

例6.4 累加数组中的元素(通过堆栈传送变量地址)

stack_strc struc

save_bp dw ?

save_cs_ip dw 2 dup (?)

par3_addr dw ?

par2_addr dw ?

par1_addr dw ? stack_strc ends

6.3 子程序举例

例6.8 十六进制到十进制的转换程序(通过寄存器传送变量)

hexidec segment; 16→10

main proc far

assume cs: hexidec

start:

push ds

sub ax, ax

push ax

repeat:

call hexibin ; 16→2

call crlf

call binidec ; 2→10

call crlf

jmp repeat

ret

main endp

hexibin proc near ; 16→2

mov bx, 0

newchar:

mov ah, 1

sub al, 30h

jl exit

cmp al, 10d

jl add_to

sub al, 27h ; ‘ a ’ ~ ‘ f ’

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: ret

hexibin endp

crlf proc near

mov dl, 0ah

mov ah, 2

int 21h

mov dl, 0dh

mov ah, 2

int 21h

ret

hexidec ends

end start

第六章作业

Page 177~182

6.4 6.5 6.9

6.13

期中作业:

(1) Hanoi塔的递归程序

(2) Fibonacci数的递归程序

(3) 字符串反序输出递归程序的改写(用STRUC伪操作)

(4) 十六进制转换成十进制程序的改写(‘a’~‘f’、‘A’~‘F’都接收)

(1)~(4)要求:* 源码

* 相应的输入/输出或Debug下的显示信息

(5) 在屏幕上显示20000以内的素数及其个数

要求:* 采用子程序结构

* 源码及相应注释

* 用BASIC和C完成相同的功能,比较它们的执行时间,

并对结果做适当分析

DOS功能调用INT 21H

用户在程序中调用DOS提供的一些子功能:

(1)一般设备的输入输出

(2)磁盘的输入输出及磁盘文件的管理

(3)其它

调用方法:

(1)设置调用参数

(2)MOV AH, 功能号

(3)INT 21H

(1)DOS键盘功能调用( AH=1,6,7,8,A,B,C )

例:单字符输入( AH=1 )

get-key: mov ah, 1

int 21h

cmp al, ‘Y’

je yes

cmp al, ‘N’

je no

jne get_key yes:

……

no:

……

(2)DOS显示功能调用( AH=2,6,9 )

例:显示单个字符( AH=2 )

mov ah, 2

mov dl, ‘A’

int 21h

例:显示字符串( AH=9 )

string db ‘HELLO’, 0dh, 0ah, ‘$’mov dx, offset string

mov ah, 9

int 21h

(3)DOS打印功能( AH=5 )

相关文档