当前位置:  编程技术>综合
本页文章导读:
    ▪探讨c++函数中的参数传递与返回值(六) 总结      第六章 总结 引用,实际上是C++为了简化指针操作,对指针的操作进行了封装,产生了引用类型。实际上引用类型就是指针类型,只不过它用于存放地址的内存空间对使用者而言是隐藏.........
    ▪线程局部存储,Part 5:加载器对__declspec(thread)变量的支持(进程初始化阶段)      原文网址:http://www.nynaeve.net/?p=186 上次,我描述了编译器和链接器为访问__declspec(thread)扩展类变量所使用的生成代码的机制。尽管此时它们已经为隐式TLS布置了舞台,但为了使整体能够工作.........
    ▪Android ViewGroup.setDescendantFocusability函数      这个函数是在ViewGroup里定义的,主要用于控制child View获取焦点的能力,比如是否阻止child View获取焦点。   他有三个常量可供设置   FOCUS_BEFORE_DESCENDANTS ViewGroup本身先对焦点进行处理,如果没.........

[1]探讨c++函数中的参数传递与返回值(六) 总结
    来源: 互联网  发布时间: 2013-11-05
第六章 总结

引用,实际上是C++为了简化指针操作,对指针的操作进行了封装,产生了引用类型。实际上引用类型就是指针类型,只不过它用于存放地址的内存空间对使用者而言是隐藏的,而且对引用的任何操作都会被重定向到其指向的变量。

    一句话,引用是一种特殊指针。

参数传递:参数传递时候,必然会发生从实参到形参的拷贝。其中:

·普通值做参数时,直接拷贝值从实参到栈上作为形参;

·指针做参数时,拷贝的是指针变量中的值,也就是其指向的变量的地址;

·引用做参数时,拷贝的是其指向的变量的地址;

·浮点数做参数时,拷贝其值到栈上,中间采用浮点指令完成;

·数组做参数时,拷贝的是数组首地址,也是作地址用;

·结构体和类做参数时,若无自定义拷贝构造函数,则依次拷贝对象域内的数据到形参(默认拷贝构造),若有自定义的拷贝构造函数,则调用构造函数在栈上构造形参。

返回值:

·普通值做返回值时,直接用eax返回;

·指针做返回值时,用eax返回指针值;

·引用做返回值时,用eax返回其指向的变量的地址,同指针;

·浮点数做返回值时,将返回值存储到浮点数栈的栈顶,也就是ST0做返回值;

·数组做返回值时,用eax返回其数组的首地址,同指针;

·结构体和类做返回对象时,

         若无自定义的拷贝构造函数,

1.对象大小不大于(<=)4字节,直接用eax返回;

                   2.对象大小大于(>)4字节,且不大于(<=)8字节,用eax和edx返回;

若存在自定义的拷贝构造函数或赋值操作符重载,或者无自定义的拷贝构造函数和赋值操作符重载但对象大小大于(>)8字节时,则隐含传入一个返回对象(可能是临时对象或者接收对象)的地址,在函数内部,对该临时对象的各成员依次赋值(默认拷贝构造),eax返回临时对象的地址。

         当返回对象被用作拷贝构造的参数去构造新对象时,直接把新对象的地址做返回对象;

当返回对象被用作assignment操作时,需要生成一个临时对象去过渡,该临时对象会被作为返回对象。


本系列结尾:

本系列文章中的重要分析部分都在反汇编代码后面的注释上,而且重点的理解也要结合代码调试去完成。

总之,实践才是检验真理的唯一标准。

作者署名:cr09philip

参考文献:钱林松《C++反汇编与逆向分析技术揭秘》


作者:cooljuly 发表于2013-1-5 11:14:26 原文链接
阅读:48 评论:0 查看评论

    
[2]线程局部存储,Part 5:加载器对__declspec(thread)变量的支持(进程初始化阶段)
    来源: 互联网  发布时间: 2013-11-05

原文网址:http://www.nynaeve.net/?p=186

上次,我描述了编译器和链接器为访问__declspec(thread)扩展类变量所使用的生成代码的机制。尽管此时它们已经为隐式TLS布置了舞台,但为了使整体能够工作,仍然需要加载器这个组件来提供必需的运行时支持。

具体的,加载器将负责为每个模块分配TLS索引值,为每个线程的TEB中的ThreadLocalStoragePointer分配内存空间。此外加载器还需要为每个模块分配TLS存储空间。

概念上,加载器中和TLS相关的分配和管理职责可以被划分为四个方面:(注意这是在Windows Server 2003版本和比其早的版本;之后将分析下Vista中所做的修改)

1.    进程初始化阶段,为变量_tls_index分配索引值,确定每个模块所需的TLS空间内存的大小,然后调用TLS和DLL初始化函数(同一模块,先调用TLS初始化函数,后调用DllMain初始化函数)。

2.    在线程初始化阶段,为每一个使用了TLS的模块分配TLS内存并初始化,根据使用TLS的模块数目为当前线程分配ThreadLocalStoragePointer数组,然后将各个模块的TLS内存和ThreadLocalStoragePointer数组中的对应项相关联。然后为当前线程调用TLS初始化函数和DLLMain初始化函数。

3.    在线程终止的时候,调用TLS初始化函数和DLLMain函数(根据参数确定是线程终止),释放当前线程中每个模块对应的TLS内存,然后释放ThreadLocalStoragePointer数组。

4.    在进程终止时,调用TLS和DLlmain初始化函数。

当然,加载器在完成上面所列工作的同时也做了其他事情;以上所列的只是TLS支持中的关键部分。

除了进程初始化以外,其它大部分操作都非常直观。进程初始化主要是由ntdll中的LdrpInitializeTls和LdrpAllocateTls两个例程来完成的。

当所有静态连接的dll文件被载入之后,所有其它初始化例程被调用之前,LdrpInitializeTls被调用(说明优先级比较高,是关键的部分)。基本上,该函数要遍历所有加载模块,为每一个具有有效TLS目录的模块统计出它使用的TLS内存的大小。对每一个使用了TLS的模块,会分配一个数据结构来记录该模块所使用的TLS内存大小并为其分配的索引号(_tls_used)。(早在Xp系统中,LDR_DATA_TABLE_ENTRY结构中的TlsIndex域貌似就没有使用了。而在WINME系统中将该值误用为模块的TLS索引,因此假定该值为-1在WINME系统中是不可靠的)

使用了TLS的模块在调用LdrpInitializeProcess的过程中将被标记为始终位于内存当中(这种模块的LoadCount值为0xFFFF)。实际中,这个不是什么问题,因为这种模块必须是静态链接的或是被主模块隐式依赖,不可能中途退场。

在函数LdrpInitializeTls为模块分类了TLS索引之后,将调用LdrpAllocateTls为初始线程初始化TLS值。

这时,进程继续初始化,最后每个模块的TLS初始化和DLLmain初始化函数会被调用。(注意应用程序主模块可以有多个TLS回调函数,但是没有DLLmain函数)

一个有意思的事情是同一个DLL模块的TLS初始化函数始终在DLL初始化函数之前调用。(这个过程按顺序进行,例如先A.dll的TLS初始化,A.dll的DLLmain初始化,B.dll的TLS初始化,B.dll的Dllmain初始化,以此类推)。这意味着在TLS初始化函数中要慎重使用CRT的函数((as the C runtime is initialized before the user’s DllMain routineis called, by the actual DLL initializer entrypoint, such that the CRT will notbe initialized when a TLS initializer for the module is invoked).)。这将非常危险,因为全局数据还没有被创建;除非导入被跳过,否则模块将处于一个完全未初始化的状态。

另一个值得一提的有关加载器对TLS支持的方面是PE文件格式标准中,IMAGE_TLS_DIRECTORY结构中的SizeOfZeroFill域并没有被链接器和加载器使用。这意味着在现实中,所有TLS模板数据都将初始化,TLS内存块的大小不像PE文件格式标准所陈述的的那样包含域SizeOfZeroFill。

一些软件滥用TLS回调来用于反调试的目的(通过创建一个TLS回调项来在入口函数获得执行权之前执行代码),虽然可以,但是实际中这点将非常明显,因为大部分PE文件都不会使用TSL回调。

直到Windows Server 2003,上述就是加载器对__declspec(thread)存储类的所有支持。这个方法看起来工作的很好,但事实上存在些问题(如果你一直看到现在,你也许会发现是什么问题)。更多关于以上方法的限制的讨论将在下一周为大家讲述。

作者:x313695373 发表于2013-1-5 11:50:21 原文链接
阅读:0 评论:0 查看评论

    
[3]Android ViewGroup.setDescendantFocusability函数
    来源:    发布时间: 2013-11-05

这个函数是在ViewGroup里定义的,主要用于控制child View获取焦点的能力,比如是否阻止child View获取焦点。

 

他有三个常量可供设置

 

  • FOCUS_BEFORE_DESCENDANTS ViewGroup本身先对焦点进行处理,如果没有处理则分发给child View进行处理
  • FOCUS_AFTER_DESCENDANTS 先分发给Child View进行处理,如果所有的Child View都没有处理,则自己再处理
  • FOCUS_BLOCK_DESCENDANTS ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理

  • 我们看下这个方法的实现
    public void setDescendantFocusability(int focusability) {
            switch (focusability) {
                case FOCUS_BEFORE_DESCENDANTS:
                case FOCUS_AFTER_DESCENDANTS:
                case FOCUS_BLOCK_DESCENDANTS:
                    break;
                default:
                    throw new IllegalArgumentException("must be one of FOCUS_BEFORE_DESCENDANTS, "
                            + "FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS");
            }
            mGroupFlags &= ~FLAG_MASK_FOCUSABILITY;
            mGroupFlags |= (focusability & FLAG_MASK_FOCUSABILITY);
        }
     

     

    可以看到,只有这三个常量可以设置,不是这三个常量会抛出异常的。

     

     

    设置后,会在requestFocus(int direction, Rect previouslyFocusedRect) 方法里根据设置进行相应的处理。来看下实现

     

    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
            if (DBG) {
                System.out.println(this + " ViewGroup.requestFocus direction="
                        + direction);
            }
            int descendantFocusability = getDescendantFocusability();
    
            switch (descendantFocusability) {
                case FOCUS_BLOCK_DESCENDANTS:
                    return super.requestFocus(direction, previouslyFocusedRect);
                case FOCUS_BEFORE_DESCENDANTS: {
                    final boolean took = super.requestFocus(direction, previouslyFocusedRect);
                    return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect);
                }
                case FOCUS_AFTER_DESCENDANTS: {
                    final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect);
                    return took ? took : super.requestFocus(direction, previouslyFocusedRect);
                }
                default:
                    throw new IllegalStateException("descendant focusability must be "
                            + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS "
                            + "but is " + descendantFocusability);
            }
        }

     

    通过这里的实现可以看到上面定义的三个常量设置的意思。。

     



    已有 0 人发表留言,猛击->>这里<<-参与讨论


    ITeye推荐
    • —软件人才免语言低担保 赴美带薪读研!—




        
    最新技术文章:
    ▪error while loading shared libraries的解決方法    ▪版本控制的极佳实践    ▪安装多个jdk,多个tomcat版本的冲突问题
    ▪简单选择排序算法    ▪国外 Android资源大集合 和个人学习android收藏    ▪.NET MVC 给loading数据加 ajax 等待loading效果
    ▪http代理工作原理(3)    ▪关注细节-TWaver Android    ▪Spring怎样把Bean实例暴露出来?
    ▪java写入excel2007的操作    ▪http代理工作原理(1)    ▪浅谈三层架构
    ▪http代理工作原理(2)    ▪解析三层架构……如何分层?    ▪linux PS命令
    ▪secureMRT Linux命令汉字出现乱码    ▪把C++类成员方法直接作为线程回调函数    ▪weak-and算法原理演示(wand)
    ▪53个要点提高PHP编程效率    ▪linux僵尸进程    ▪java 序列化到mysql数据库中
    ▪利用ndk编译ffmpeg    ▪活用CSS巧妙解决超长文本内容显示问题    ▪通过DBMS_RANDOM得到随机
    ▪CodeSmith 使用教程(8): CodeTemplate对象    ▪android4.0 进程回收机制    ▪仿天猫首页-产品分类
    ▪从Samples中入门IOS开发(四)------ 基于socket的...    ▪工作趣事 之 重装服务器后的网站不能正常访...    ▪java序列化学习笔记
    ▪Office 2010下VBA Addressof的应用    ▪一起来学ASP.NET Ajax(二)之初识ASP.NET Ajax    ▪更改CentOS yum 源为163的源
    ▪ORACLE 常用表达式    ▪记录一下,AS3反射功能的实现方法    ▪u盘文件系统问题
    ▪java设计模式-观察者模式初探    ▪MANIFEST.MF格式总结    ▪Android 4.2 Wifi Display核心分析 (一)
    ▪Perl 正则表达式 记忆方法    ▪.NET MVC 给loading数据加 ajax 等待laoding效果    ▪java 类之访问权限
    ▪extjs在myeclipse提示    ▪xml不提示问题    ▪Android应用程序运行的性能设计
    ▪sharepoint 2010 自定义列表启用版本记录控制 如...    ▪解决UIScrollView截获touch事件的一个极其简单有...    ▪Chain of Responsibility -- 责任链模式
    ▪运行skyeye缺少libbfd-2.18.50.0.2.20071001.so问题    ▪sharepoint 2010 使用sharepoint脚本STSNavigate方法实...    ▪让javascript显原型!
    ▪kohana基本安装配置    ▪MVVM开发模式实例解析    ▪sharepoint 2010 设置pdf文件在浏览器中访问
    ▪spring+hibernate+事务    ▪MyEclipse中文乱码,编码格式设置,文件编码格...    ▪struts+spring+hibernate用jquery实现数据分页异步加...
    ▪windows平台c++开发"麻烦"总结    ▪Android Wifi几点    ▪Myeclipse中JDBC连接池的配置
    ▪优化后的冒泡排序算法    ▪elasticsearch RESTful搜索引擎-(java jest 使用[入门])...    ▪MyEclipse下安装SVN插件SubEclipse的方法
    ▪100个windows平台C++开发错误之七编程    ▪串口转以太网模块WIZ140SR/WIZ145SR 数据手册(版...    ▪初识XML(三)Schema
    ▪Deep Copy VS Shallow Copy    ▪iphone游戏开发之cocos2d (七) 自定义精灵类,实...    ▪100个windows平台C++开发错误之八编程
    ▪C++程序的内存布局    ▪将不确定变为确定系列~Linq的批量操作靠的住...    ▪DIV始终保持在浏览器中央,兼容各浏览器版本
    ▪Activity生命周期管理之三——Stopping或者Restarti...    ▪《C语言参悟之旅》-读书笔记(八)    ▪C++函数参数小结
    ▪android Content Provider详解九    ▪简单的图片无缝滚动效果    ▪required artifact is missing.
    ▪c++编程风格----读书笔记(1)    ▪codeforces round 160    ▪【Visual C++】游戏开发笔记四十 浅墨DirectX教程...
    ▪【D3D11游戏编程】学习笔记十八:模板缓冲区...    ▪codeforces 70D 动态凸包    ▪c++编程风格----读书笔记(2)
    ▪java设计模式-观察者模式初探    ▪MANIFEST.MF格式总结    ▪Android 4.2 Wifi Display核心分析 (一) iis7站长之家
    ▪markdown    ▪[设计模式]总结    ▪网站用户行为分析在用户市场领域的应用
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3