浅议C /CLI的gcnew关键字(2)

成功分配后,会把返回地址放在eax中。
  2.调用gcnew方式分配

int^ rInt = gcnew int;
0000005d mov ecx,788EF9D8h
00000062 call FCFAF66C
。。。
Foo^ rFoo = gcnew Foo;
00000072 mov ecx,3B51768h
00000077 call FCFAF66C


  能够看到gcnew也是通过把一个参数放到ecx中,然后再调用一个函数来完成分配的操作,显然0x788EF9D8应该是个地址,而不可能是个数值。我们能够看到这里gcnew创建两个不同类型的变量,调用的函数地址却都是0xFCFAF66C,而存放到ecx中的两个地址就不相同。究竟这几个地址代表什么呢?
  和new相同gcnew也是把返回地址放在eax中。我们直接从内存窗口看eax指向的内存块好了。Aha,看到了没有?

  这次的eax = 0x00F73404 对应的内存块为

0x00F73404 d8 f9 8e 78 00 00 00 00 。。。

  这个不就是 mov 到 ecx中的值么?再回忆昨天写的分析Object对象布局的文章,能够肯定这个就是 MethodTable地址了,对于这个int来说,后面的4个字节对应的就是存放他的RawData,比如假如您初始化为 4 那么内存对应的就变化为 d8 f9 8e 79 04 00 00 00
  分析清楚存放到ecx中的是 MethodTable指针,我们再分析那个对应的call函数,从vm的代码能够看出,有三个全局函数用来根据MethodTable创建对象,同时MethodTable本身也提供一个成员函数Allocate(),只但是这个成员函数也是调用的下面的函数:

OBJECTREF AllocateObject( MethodTable *pMT )
OBJECTREF AllocateObjectSpecial( MethodTable *pMT )
OBJECTREF FastAllocateObject( MethodTable *pMT )
  其中AllocateObject又是调用AllocateObjectSpecial来完成工作。那么我们调用的应该就是AllocateObject或FastAllocateObject了。

  在我们的例子里面两个call的地址都相同,但是您假如写下代码 double ^ pDouble = gcnew double;这个时候的地址是多少?他和int 的相同么?

  现在我还没有仔细去研究这个地址到底对应的是该类型的MethodTable::Allocate()或是上面的这三个全局函数,假如对应MethodTable::Allocate(),那么2.0中应该有个MethodTable::FastAllocate()吧,否则应该就是对应的全局函数AllocateObject 连同FastAllocateObject了。过几天一定要抽空再好好研究一下。
  下面看对应的delete函数。

delete pInt;
000000d8 mov ecx,dword ptr [esp 18h]
000000dc call dword ptr ds:[03B51540h]
比较简单,就是传入地址,然后调用operator delete来释放类存,会调用析构函数

  对应的,释放gcnew创建的对象的代码如下:

delete rInt;
000000ac mov edx,edi
000000ae mov ecx,788F747Ch
000000b3 call FC8D20FD


  这个也相对简单,他对应vm里面的一个函数:
void CallFinalizer(Thread* FinalizerThread, Object* fobj)

  那么也就是
fobjà edx
FinalizerThread à ecx
Call CallFinalizer

  但是,请注意!!!!!!!一个类包含析构函数和不包含析构函数,他对应的delete代码是不相同的,这点能够通过汇编代码比较得到,我这里就不多说了。


转自:http://www.west.cn/info/html/chengxusheji/C-C--/20080224/9240_2.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值