利用call与ret实现段内子函数

CALL  标号:

1.指令加载进指令缓冲器

2.(IP)=(IP)+3(CALL 标号所占字节)

3.(SP)=(SP)-2

4.IP的值入栈((SS)*16+SP)=(IP)

5.IP跳转至标号行偏移地址

6.执行CS:IP

RET

1.指令加载进指令缓冲器

2.(IP)=((SS)*16+SP)

3.(SP)=(SP)+2

4.执行CS:IP

程序设计结构:

ASSUME CS:CODE,SS:STACK

STACK SEGMENT  ;建立栈空间
  ...
STACK ENDS

CODE SEGMENT
MAIN:          ;主函数
     .
     .
     .
     CALL SUB1 ;执行子函数SUB1
     . 
     .
     MOV AX,4C00H ;退出程序
     INT 21H

SUB1:
     .
     .
     CALL SUB2 ;执行子函数SBU2
     .
     .
     RET  ;函数返回
SUB2:
     .
     .
     RET  ;函数返回
CODE ENDS
END MAIN

例如,实现在窗口打印的子函数

ASSUME CS:T22,SS:STACK,DS:DATA

STACK SEGMENT
  DB 16 DUP (16)
STACK ENDS

DATA SEGMENT
  DB 16 DUP (16)
DATA ENDS

T22 SEGMENT
MAIN:
  MOV AX,STACK
  MOV SS,AX
  MOV SP,16
  MOV AX,DATA
  MOV DS,AX

  MOV CX,16      ;将需要打印的数据放在DATA
  MOV BX,0
S:MOV BYTE PTR DS:[BX],1H 
  INC BX
LOOP S

  CALL PRINT

  MOV AX,4C00H ;退出程序
  INT 21H
PRINT:
  MOV AX,0B800H
  MOV ES,AX
  MOV BX,0
  MOV CX,16
  MOV SI,0
S0:
  MOV AL,DS:[BX]  ;从DATA中读出,加载进显示缓冲区第0页
  ADD AL,96       ;ASCII
  MOV AH,02H      ;黑底绿色字
  MOV ES:[SI+0A0H],AX
  INC BX
  ADD SI,2
LOOP S0
  RET
T22 ENDS
END MAIN

猜你喜欢

转载自blog.csdn.net/wu58430/article/details/118096794