- 栈的定义及规则:
- 栈从高位到底位顺序来排列数据, 栈顶<=栈底 && 栈顶>=0, 栈顶始终指向最顶端的数据.
- Push(EAX) : TOP--, S[TOP]=EAX; //先减栈顶, 再进数据
- Pop(EAX) : S[TOP]=EAX, TOP++; //先出数据,再加栈顶
- 初始值:
- EBP=ESP=20 (EBP-ESP=0,0个数据)
- 假如有以下栈段(Step0)与函数ST():
- STACK 0-19 //定义栈开始位置0,共20字节
- 0 0 0 0 0 0
- 1 1 1 1 1 1
- 2 2 2 2 2 2
- 3 3 3 3 3 3
- 4 4 4 4 4 4
- 5 5 5 5 5 5
- 6 6 6 6 6 6 z ->ESP
- 7 7 7 7 7 7 y
- 8 8 8 8 8 8 x
- 9 9 9 9 s[3] ->ESP 9 s[3] ->EBP=ESP 9 s[3] ->EBP
- 10 10 10 10 s[2] 10 s[2] 10 s[2]
- 11 11 11 11 s[1] 11 s[1] 11 s[1]
- 12 12 12 12 s[0] 12 s[0] 12 s[0]
- 13 13 13 r[3] ->ESP 13 r[3] 13 r[3] 13 r[3]
- 14 14 14 r[2] 14 r[2] 14 r[2] 14 r[2]
- 15 15 15 r[1] 15 r[1] 15 r[1] 15 r[1]
- 16 16 16 r[0] 16 r[0] 16 r[0] 16 r[0]
- 17 17 'a' ->ESP 17 'a' 17 'a' 17 'a' 17 'a'
- 18 18 'b' 18 'b' 18 'b' 18 'b' 18 'b'
- 19 19 'c' 19 'c' 19 'c' 19 'c' 19 'c'
- Step0 step1 step2 step3 step4 step5
- 函数定义
- function ST (char a, char b, char c)
- {
- char x=a;
- char y=b;
- char z=c;
- char n=x+y+z;
- }
- 下面让我们来详细描述一下函数调用时,栈是如何使用的:
- 1.将参数压栈:
- push 'c' ESP-- ESP=19 S[19]='c'
- push 'b' ESP-- ESP=18 S[18]='b'
- push 'a' ESP-- ESP=17 S[17]='a'
- 执行后如图:step1
- 2.CALL 函数地址
- 将下一个指令的地址压栈,作为函数的返回地址char r[4](4字节的地址)
- push(r[0]) ESP-- ESP=16 S[16]=r[0]
- push(r[1]) ESP-- ESP=15 S[15]=r[1]
- push(r[2]) ESP-- ESP=14 S[14]=r[2]
- push(r[3]) ESP-- ESP=13 S[13]=r[3]
- 注意:整形数据压栈的字节顺序是从低字节到高字节压栈,形成的顺序跟内存中的整数顺序相反
- 执行后如图:step2
- 3.函数体--保护栈底(EBP)
- char s[4]=EBP;
- push(s[0]) ESP-- ESP=12 S[12]=s[0]
- push(s[1]) ESP-- ESP=11 S[11]=s[1]
- push(s[2]) ESP-- ESP=10 S[10]=s[2]
- push(s[3]) ESP-- ESP=9 S[9] =s[3]
- 执行后如图:step3
- 4.函数体--设置栈底&&保存栈顶(ESP)
- MOV EBP,ESP //EBP=ESP
- 执行后如图:step4
- 5.函数体--声明局部变量
- SUB ESP,0x03 //定义3个局部变量 x,y,z 总长度3个字节,ESP=ESP-3=5
- 执行后如图:step5
- 6.函数体--使用参数与局部变量
- //参数
- a=[EBP+8];
- b=[EBP+9];
- c=[EBP+10];
- //局部变量
- x=[EBP-1];
- y=[EBP-2];
- z=[EBP-3];
- 7.函数体--恢复栈顶(ESP)
- MOV ESP,EBP
- 8.函数体--恢复栈底(EBP)
- POP EBP
- 9.返回调用函数
- RET,相当于下面指令
- POP EDX // EDX=r[4] 让EDX等于返回地址
- JMP EDX // 跳转到EDX
- 此时,EBP=ESP=20,又恢复到函数调用前的栈状态
栈,函数,参数,局部变量之间的关系
最新推荐文章于 2024-10-22 08:00:00 发布