分类: WINDOWS
2007-10-23 16:24:35
汇编过程的学习
参考来自《80x86汇编语言程序设计-王成耀 编》
过程调用
语法格式:
CALL ProcName ; 若ProcName与该指令在同一代码段,则为段内直接调用:
; IP进栈,IP = label的偏移地址;
; 若ProcName与该指令不在同一代码段,则为段间直接调用:
; CS:IP 进栈,CS:IP = label的分段地址
CALL reg16/mem16 ; 段内间接调用:IP进栈,IP = reg16 / [mem16]
CALL mem32 ; 段间间接调用:
; CS:IP 进栈,CS = mem32高字,IP = mem32低字
功能描述:
(1)返回地址进栈。
远调用:CS与IP(下一条指令的地址)依次进栈。
(2)转移到过程的近调用:IP(下一条指令的16位偏移地址)进栈。第1条指令去执行。
远调用:根据操作数,将32位分段地址送CS:IP。
近调用:根据操作数,将16位偏移地址送IP。
对标志位的影响:无。
过程返回
RET指令RET(Return):过程返回
过程返回分为近(段内)返回和远(段间)返回。
语法格式:
RET ; 近返回或远返回
RET imm16 ; 近返回或远返回,并调整堆栈:SP = SP + imm16
功能描述:
RET:返回地址出栈,从而实现转移到返回地址处。其中,
远返回:POP 1个双字到CS:IP。
近返回:POP 1个字到IP。
RET imm16:在返回地址出栈后,CPU立即将imm16加到堆栈指针SP。这种机制用来在返回前将参数从栈中移出。
对标志位的影响:无。
说明:RET由汇编器根据其所在过程的类型(NEAR或FAR)决定是近返回还是远返回。缺省为近返回。
使用过程应注意的问题
• 若过程只在同一代码段中被调用,则定义为NEAR。
• 若过程可以在不同代码段中被调用,则定义为FAR。
过程的参数传递
对于大多数过程,需要与调用者之间传递一定数量的数据,即参数。根据传递的方向,将参数分为两类:
根据问题的需要,过程可以只有入口参数或只有出口参数,也可以二者兼有。
对于过程与调用者之间的参数传递,可根据传递的数据量,选择采用寄存器、变量或堆栈等方式。由于过程是相对独立的功能块,因此,在定义过程时,通常要加上适当的注释,主要包括功能、入口参数与出口参数等。
6.2.1 |
用变量传递参数 |
6.2.2 |
用寄存器传递参数 |
6.2.3 |
用地址表传递参数 |
6.2.4 |
用堆栈传递参数 |
6.2.5 |
用代码流传递参数 |
下面通过一个例子来对比一下这五种传递参数方法的不同。
例子:求带符号字数组ARRAY的最大值。设元素个数(大于0)由变量COUNT定义,将结果存入变量MAX中。
6.2.1 |
用变量传递参数 |
在程序中定义全局变量,如放在数据段,过程可直接按名访问该变量。
过程直接以变量作为参数,虽然方便,但通用性较差。
DESG SEGMENT |
||
COUNT |
DW 5 |
;DW:1个字,即16bit或两个字节 |
ARRAY |
DW 8,-1,32766,0,100 |
;32766=7FFEH |
MAX |
DW ? |
|
DESG ENDS |
||
CSEG SEGMENT |
||
ASSUME CS:CSEG,DS:DSEG | ||
START: |
MOV AX,DSEG |
|
MOV DS,AX |
||
CALL FINDMAX |
||
MOV AH,4CH |
||
INT 21H |
||
FINDMAX PROC |
||
MINSW |
= 8000H |
;16位带符号数的最小值 |
PUSH AX |
||
PUSH BX |
||
MOV AX,MINSW |
||
MOV BX,0 |
||
MOV CX,COUNT |
||
NEXT: |
CMP AX,ARRAY[BX] |
|
JG SKIP |
||
SKIP: |
ADD BX,2 |
|
LOOP NEXT |
||
MOV MAX,AX |
||
POP BX |
||
POP AX |
||
RET |
;一定不要忘记 | |
FINDMAX ENDP |
||
CSEG ENDS |
||
END START |