16位汇编学习记录总结(5)
第26节 2012.12.05
一、子程序的功能调用
** 调用子程序前必须将下一条指令地址 PUSH
有段内、段间区分
近调用、进返回、远调用、远返回
(1)段内过程调用指令
CALL DST
SP<- SP
[SP]<- IP
IP<- IP+disp(机器中指令的偏移地址)
(2)段内间接调用
CALL OPRD(字存储单元)
CALL BX(十六位寄存器)
(3)段间直接调用
CALL 过程名
CALL FAR PTR SUBRO
先把返回地址的断值压入堆栈,再把返回地址的偏移压栈,返回时分别送CS,IP
(4)段间间接调用
CALL OPRD;;;双字存储单元
先把返回地址的断值压入堆栈,再把返回地址的偏移压栈,低字送IP,高字送CS
2,返回指令
(1),段内返回指令:
RET
IP<- [SP]
SP<- SP+2
(2),段间返回指令
IP<- SP
SP<- SP+2
CS<- SP
SP<- SP+2
(3),段内含立即数返回指令
RET 表达式
将表达式的结果data取整
IP<- SP
SP<- SP+2
SP<- SP+data
修改堆栈指针用的
(4)段间带立即数返回指令
RET 表达式
IP<- SP
SP<- SP+2
CS<- SP
SP<- SP+2
SP<- SP+data
二、过程定义语句
过程名 PROC [NEAR |FAR ]
:
:
过程名 ENDP
第二十七节
子程序举例
data segment
org 1000h
block db 48h,80h
resul db ?
data ends
stack segment para stack 'stack'
db 64 dup(?)
stack ends
code segment
assume cs:code,ss:stack,ds:data
start proc
begin:
mov ax,data
moc ds,ax
mov sp,4000h
lea bx,block
mov al,[bx]
sub al,[bx+1]
push ax
pushf
call sub1
popf
pop ax
mov [bx+2],al
hlt
ret
start endp
sub1 proc
add al,al
ret
sub1 endp
code ends
end begin
----------------------------------------------------------------------------
第二十八节
子程序说明信息
(1)子程序名
(2)功能描述
(3)入口和出口参数
(4)所用寄存器和存储单元
(5)使用的算法和重要的性能指标
(6)其他调用注意事项和说明信息
(7)调用实例
;;将十六位的二进制数转换为4位十六进制的ASCII码的子程序
;;入口参数:DX=欲转换的二进制数
;;DS:BX=存放转换所得ASCII码串的缓冲区首地址
;;出口参数:十六进制数ASCII码串按高到低一次存放在指定的缓冲区中
htascs proc
mov cx,4
rol dx,1
rol dx,1
rol dx,1
rol dx,1
mov al,dl
call htoasc
mov [bx],al
inc bx
loop htascs1
ret
htascs endp
htoasc proc near
and al,0fh
add al,30h
cmp al,39h
jbe htoasc1
add al,7
htoasc1:
ret
htoasc endp
--------------------------------------------------
主程序与子程序的参数传递
参数传递的方法:
寄存器传递法: 参数较少的情况
约定内存单元传递法:
堆栈传递法
CALL后续传递法
----------------------------
;;大写字母转换为小写字母
datoxia proc
pushf
cmp al,'A'
jb datoxia1
cmp al,'Z'
ja datoxia1
add al,20h
datoxia1:
popf
datoxia endp
-------------------------------
;;删除字符串中的数字
dseg segment
string db 'ab=c950=asd',0
dseg ends
cseg segment
assume cs:cseg,ds:dseg
isdecm proc
cmp al,'0'
jb ren
cmp al,'9'
ja ren
clc ;;CF=0
ren:
stc ;;CF=1
ret
isdecm endp
start: mov ax,dseg
mov ds,ax
mov si,offset string
mov di,si ;;**
next: mov al,[si] ;;;源址
inc si
or al,al
jz ok
call isdecm
jnc next
mov [di],al ;;目的变址
inc di
jmp next
ok: mov [di],al
mov ah,4ch
int 21h
seg ends
end start