这种技术和高级语言编译器的工作原理密切相关。我们下面结合 C 语言的函数调用,看一下用栈传递参数的思想。
用栈传递参数的原理十分简单,就是由调用者将需要传递给子程序的参数压入栈中,子程序从栈中取得参数。我们看下面的例子。
;说明:计算( a – b ) ^ 3 ,a、b 为 word 型数据。
;参数:进入子程序时,栈顶存放IP,后面依次存放 a、b
;结果:( dx : ax ) = ( a – b ) ^ 3 ( 乘法,两个数都是8位,结果存放在AX中;如果两个数都是16位,高位存放在DX中,低位存放在AX中 )
difcube :
push bp
mov bp , sp
mov ax , [ bp + 4 ] ; 将栈中a的值送入ax 中
sub ax , [ bp + 6 ] ; 减栈中b的值
mov bp , ax
mul bp
mul bp
pop bp
ret 4 ; call 返回,并恢复sp
指令 ret n 的含义用汇编语法描述为:
pop ip
add sp , n
因为用栈传递参数,所以调用者在调用程序的时候要向栈中压入参数,子程序在返回的时候可以用ret n 指令将栈顶指针修改为调用前的值。调用上面的子程序之前,需要压入两个参数。所以用ret 4 返回。
我们看一下如何调用上面的程序,设 a = 3 、b = 1 ,下面的程序段计算:( a – b ) ^ 3:
mov ax , 1
push ax
mov ax , 3
push ax ;注意参数压栈的顺序
call difcube
|
我们看一下程序的执行过程中栈的变化:
(1)假设栈的初始情况如下:
1000:0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
↑ss:sp
(2)执行以下指令:
mov ax , 1
push ax
|