Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1400603
  • 博文数量: 416
  • 博客积分: 13005
  • 博客等级: 上将
  • 技术积分: 3297
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 16:26
文章分类

全部博文(416)

文章存档

2014年(1)

2013年(4)

2012年(46)

2011年(64)

2010年(12)

2009年(4)

2008年(40)

2007年(187)

2006年(58)

分类: 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)返回地址进栈。

             远调用:CSIP(下一条指令的地址)依次进栈。

          

2)转移到过程的近调用:IP(下一条指令的16位偏移地址)进栈。第1条指令去执行。

            远调用:根据操作数,将32位分段地址送CS:IP

            近调用:根据操作数,将16位偏移地址送IP

    对标志位的影响:无。

过程返回

RET指令RETReturn):过程返回

        过程返回分为近(段内)返回和远(段间)返回。

        语法格式:

              RET  ; 近返回或远返回

              RET          imm16          ; 近返回或远返回,并调整堆栈:SP = SP + imm16

        功能描述:

             RET:返回地址出栈,从而实现转移到返回地址处。其中,

                   远返回:POP 1个双字到CS:IP

                   近返回:POP 1个字到IP

            RET  imm16:在返回地址出栈后,CPU立即将imm16加到堆栈指针SP。这种机制用来在返回前将参数从栈中移出。

        对标志位的影响:无。

        说明:RET由汇编器根据其所在过程的类型(NEARFAR)决定是近返回还是远返回。缺省为近返回。

 

使用过程应注意的问题

    •  在过程体内必须有一条RET指令被执行到。如果在过程内没有执行到RET或其它转移指令,程序将继续执行ENDP后的指令。
    •  正确选择过程的类型。通常基于下列原则:

     若过程只在同一代码段中被调用,则定义为NEAR

     若过程可以在不同代码段中被调用,则定义为FAR

    •  CALLRET的类型要一致。
    •  通常要保证RET指令执行前,栈顶内容正好是返回地址。
    •  注意保护相关寄存器的值。通常,除了作为返回参数的寄存器外,过程不应改变其它寄存器的值。
    •  可以将过程定义放在单独的代码段中。若过程定义与主程序处于同一代码段,则要保证其只有被调用时,才会执行。
    • 一个过程可以调用另一个过程,甚至可以自己调用自己。

过程的参数传递

对于大多数过程,需要与调用者之间传递一定数量的数据,即参数。根据传递的方向,将参数分为两类:

    •  入口参数:由调用者向过程传递的数据,作为过程的输入参数。
    •  出口参数:由过程向调用者返回的数据,作为过程的输出参数。

        根据问题的需要,过程可以只有入口参数或只有出口参数,也可以二者兼有。

        对于过程与调用者之间的参数传递,可根据传递的数据量,选择采用寄存器、变量或堆栈等方式。由于过程是相对独立的功能块,因此,在定义过程时,通常要加上适当的注释,主要包括功能、入口参数与出口参数等。

 

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

;DW1个字,即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

阅读(2179) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~