ITEEDU

2、在子程序中取入口参数的方法:

  • 段内调用子程序
  • 由于是段内调用,所以,CALL指令只把返回地址的偏移量(即IP的内容)压栈,如图7.6(a)所示。在进入子程序后,为了能读取传递过来的参数,需要用BP来访问堆栈,所以要先保护BP原来的值,再把当前SP的值传送给BP。

    于是,当前BP所指向的堆栈单元与最后一个参数Paran之间隔着BP的原值和返回地址的偏移量,也就是说:二者之间相差4个字节。具体情况如图7.6(b)所示。

    (a)、进入子程序时堆栈情况

     

    (b)、子程序寄存器保护后的堆栈情况

    图7.6 在段内调用情况下子程序所能访问的堆栈情况

    在子程序中读取用堆栈传递参数的一般方法如下程序片段所示。

    
    SUBPRO PROC?NEAR
    
    PUSH BP ;保护寄存器BP
    
    MOV BP, SP ;用寄存器BP来访问堆栈,读取参数 
    
    … ;保护其它寄存器的指令 
    
    MOV Paran, [BP+4] ;保护其它寄存器的指令 
    
    …
    
    MOV Para1, [BP+4+2*(n-1)]
    
    …
    
    SUBPRO ENDP
    
    
  • 段间调用子程序
  • 在段间调用子程序时,CALL指令会把返回地址的偏移量和段寄存器CS的内容都压栈,如图7.7(a)所示。在进入子程序后,与前面“段内调用子程序”一样,也需要用BP来读取传递过来的参数,所以,也要先保护BP原来的值,再把当前SP的值传送给BP。

    这时,当前BP所指向的堆栈单元与最后一个参数Paran之间隔着BP的原值、返回地址的偏移量和段地址,所以,二者之间相差6个字节。具体情况如图7.7(b)所示。

    (a)、进入子程序时堆栈情况

    (b)、子程序寄存器保护后的堆栈情况

    图7.7 在段间调用情况下子程序所能访问的堆栈情况

    在段间调用时,除了多一个返回段地址外,其它的内容与“段内调用”的情况完全一致,所以,在读取第i个参数时,只要用[BP+6+4*(n-i)]代替[BP+4+2(n-i)]即可(假设每个参数都是字类型)。