练习3:参数值传递的汇编实质
2013-05-10 19:13
148 查看
参数值传递的汇编实质,就是在堆栈上创建存储区,看看以下实现:
先来看看Delphi代码,传一个数组参数进去
调用代码为:
看看汇编代码是怎样干的:
函数入口:
函数退出时:
先来看看Delphi代码,传一个数组参数进去
procedure SortIt(a: array of Integer); var i, j: Integer; begin j := Length(a); for i:=1 to j do a[i-1] := i; end;
调用代码为:
procedure TForm1.btn1Click(Sender: TObject); var a: array[0..1] of Integer; begin SortIt(a); ShowMessage('a[0]: ' + IntToStr(a[0]) + #13#10 + 'a[1]: ' + IntToStr(a[1])); end;
看看汇编代码是怎样干的:
Unit1.pas.44: SortIt(a); ;调用前准备 lea eax,[ebp-$08] ;定义的局部变量放在堆栈里,2个数组元素,32位系统里占8字节, ;根据定义的局部变量顺序压栈,这儿只定义了数组A,所以堆栈里 ;就只有8字节,此句的意思是,把ebp-8的值放到eax中,这个值是 ;指向a[1]的内存地址,所以执行后eax中为a[0]元素的内存地址 mov edx,$00000001 call SortIt
函数入口:
;函数入口处代码 00452688 55 push ebp ;这两行为堆栈框架,函数开始前必这样做以保存调用前 00452689 8BEC mov ebp,esp ;的堆栈数据,同时为同时为函数创造干净的堆栈环境 0045268B 53 push ebx ;要用到ebp,先保存原值,不要破坏它 0045268C 8BCA mov ecx,edx ;edx值为1,看起来用于下面的循环,ecx一般用于计数 0045268E 85C9 test ecx,ecx ;test和and类似,不同的是,只影响标志寄存器,不影响结果 00452690 7807 js +$07 ;如果sf为1,这是符号位,如果ecx为ffff ffff,数组就爆了,不能是大于这个值 00452692 8B1C88 mov ebx,[eax+ecx*4] ; 记得eax为a[0]吧,此处ecx为1, eax+4刚好为a[1]地址,把a[1]的值取到ebx 00452695 49 dec ecx 00452696 53 push ebx ; 把a[1]值入栈 00452697 79F9 jns -$07 ;返回上面的mov ebx,[eax+ecx*4],再来一次,这样的话又能把a[0]值入栈 00452699 8BC4 mov eax,esp ;这个时候堆栈里从低地址到高地址已形成a[0]、a[1]的结构,把堆栈指针指向a[0], ;一个新的临时参数环境就构造好了,后面对数组的存取就只在这儿进行,不会影响 ;原值,高明呀,原来是这样实现的!
函数退出时:
;函数结束堆栈要恢复到入来前的状态,这叫堆栈平衡 004526B5 8BE5 mov esp,ebp ;记得函数进来前ebp指向栈顶吧,这一下直接回到进来前状态 004526B7 5D pop ebp ;是push ebp和mov ebp,esp的倒过来,就恢复了。 004526B8 C3 ret
相关文章推荐
- Delphi与汇编笔记(3)------关于参数的传递
- [转] c# 的传递参数值传递与传递引用的区别,ref与out区别
- 汇编(十四)——串操作类指令练习
- 汇编中参数的传递和堆栈修正
- Javascript中循环时怎么传递参数值
- Ant系列六: ant中参数值传递
- 汇编中参数的传递和堆栈修正
- 反汇编练习-20170111
- 汇编中参数的传递和堆栈修正
- jquery post方式传递多个参数值后台以数组的方式进行接收
- 编译器是如何用汇编语言实现C++的虚函数表和隐式传递this指针(一)
- Delphi与汇编笔记(3)------关于参数的传递
- Extjs练习——服务器端获取信息填充客户端表单,注意Radio以及Checkbox值的传递
- js获取url参数值,js获取其他页面传递而来的值
- 揭秘ECMAScript参数值传递与“引用”传递
- 【基础练习】【传递闭包】codevs1506 传话题解
- js中函数参数值传递和引用传递
- 反汇编练习-2016-1130
- C函数与汇编函数之间参数及返回值传递方法
- JMeter中3种参数值的传递