//=====================================================================
//TITLE:
//    灵活使用ARM汇编的WEAK关键字
//AUTHOR:
//    norains
//DATE:
//    Tuesday  20-October-2010
//Environment:
//    KEIL MDK 4.0
//=====================================================================

ARM汇编中的WEAK关键字是一个很有意思的功能,如果能够灵活使用,能减轻不少繁琐。一般来说,这个关键字使用在IMPORT和EXPORT这两个声明段。

如果我们有一个名为ARM_Vectors的量表,向量表的第一个数值指向一个StackTop函数的地址。因为我们可能定义了该函数,也可能没有,为了代码的简便,我们可以使用WEAK关键字,如:

////////////////////////////////////////////////////////////////////////////
//VectorsTrampolines.s
////////////////////////////////////////////////////////////////////////////
IMPORT     StackTop [WEAK]

 AREA |.text|, CODE, READONLY 
;Vector list
ARM_Vectors
   DCD     StackTop

当我们定义了StackTop函数后,那么ARM_Vectors里第一个向量值就是StackTop函数的地址。如果没有定义StackTop,那么编译器不会报错,而这时候第一个向量值就直接赋予0。

那么对于EXPORT,WEAK又有什么样的功能呢?如果你EXPORT的函数带有WEAK标志的话,并且别的源代码没有定义同名函数,那么连接时就是该函数;否则,就是另外的一个同名函数。这个机制,和类的继承有点相像,都是一个函数将另一个函数给掩盖了;所不同的是,WEAK里的这个掩盖,是彻彻底底让另外一个函数消失。

可能这样说还是有点不太明白,我们以实例来说明:

////////////////////////////////////////////////////////////////////////////
//VectorsTrampolines.s
////////////////////////////////////////////////////////////////////////////
 IMPORT     StackTop 
 AREA |.text|, CODE, READONLY 
;Vector list
ARM_Vectors
   DCD     StackTop

////////////////////////////////////////////////////////////////////////////
//VectorsHandlers.s
////////////////////////////////////////////////////////////////////////////
EXPORT  StackTop               [WEAK]
 AREA    |i.DefaultHandler|, CODE, READONLY
StackTop     PROC                
                B       .
                ENDP

虽然这时候StackTop在通过EXPORT导出时带有WEAK关键字,但因为整个源代码文件中只有这里有StackTop,所以VectorsTrampolines.s文件中连接的StackTop是VectorsHandlers.s定义的同名函数。

如果另外的源代码也定义了同名的函数,如:

////////////////////////////////////////////////////////////////////////////
//VectorsTrampolines.s
////////////////////////////////////////////////////////////////////////////
 IMPORT     StackTop 
 AREA |.text|, CODE, READONLY 
;Vector list
ARM_Vectors
   DCD     StackTop

////////////////////////////////////////////////////////////////////////////
//VectorsHandlers.s
////////////////////////////////////////////////////////////////////////////
EXPORT  StackTop               [WEAK]
 AREA    |i.DefaultHandler|, CODE, READONLY
StackTop     PROC                
                B       .
                ENDP

////////////////////////////////////////////////////////////////////////////
//Func.c
////////////////////////////////////////////////////////////////////////////
Extern “C” StackTop()
{}

因为VectorsHandlers.s的StackTop是用WEAK导出的,而Func.c又有同名的函数,那么这时候VectorsTrampolines.s里的StackTop是连接Func.c里定义的StackTop。

这里有一个很有意思的问题,如果EXPORT和IMPORT都用WEAK声明,如:

////////////////////////////////////////////////////////////////////////////
//VectorsTrampolines.s
////////////////////////////////////////////////////////////////////////////
 IMPORT     StackTop  [WEAK]
 AREA |.text|, CODE, READONLY 
;Vector list
ARM_Vectors
   DCD     StackTop

////////////////////////////////////////////////////////////////////////////
//VectorsHandlers.s
////////////////////////////////////////////////////////////////////////////
EXPORT  StackTop               [WEAK]
 AREA    |i.DefaultHandler|, CODE, READONLY
StackTop     PROC                
                B       .
                ENDP

这时候VectorsTrampolines.s里的ARM_Vectors的第一个向量值是什么呢?还是VectorsHandlers.s里的StackTop函数地址么?很遗憾,不是,而直接是0!所以这点就注意了,最好不要对同名的函数在IMPORT和EXPORT时都使用WEAK,否则结果很可能让你抓狂!

最后,以一个列表作为总结:

VectorsTrampolines.s

VectorsHandlers.s

Func.c

ARM_Vectors第一个向量值

IMPORT     StackTop [WEAK]

0

IMPORT     StackTop [WEAK]

EXPORT  StackTop

VectorsHandlers.s的StackTop地址

IMPORT     StackTop

EXPORT StackTop    [WEAK]

有同名的StackTop函数

Func.c的StackTop地址

IMPORT     StackTop

EXPORT StackTop

有同名的StackTop函数

存在两个StackTop,编译出错

IMPORT  StackTop [WEAK]

EXPORT StackTop   [WEAK]

0

 

灵活使用ARM汇编的WEAK关键字的更多相关文章

  1. 汇编的WEAK关键字

    一般来说,这个关键字使用在IMPORT和EXPORT这两个声明段. ////////////////////////////////////////////////////////////////// ...

  2. 经常使用ARM汇编指令

    一面学习,一面总结,一面记录. 以下是整理在网上找到的一些资料,简单整理记录一下,方便以后查阅. ARM处理器的指令集能够分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.载入/存储指令. ...

  3. ARM汇编编程概述

    1.为什么需要学些汇编指令 2.ARM汇编指令分类 3.汇编程序框架 4.编程准备 +++++++++++++++++++++++++++++++++++ 1.为什么需要学些汇编指令 bootload ...

  4. C/C++ 中嵌入 arm 汇编

    GCC编译器支持直接在C或者C++代码中,嵌入ARM汇编代码.其基本格式非常简单,大致如下: __asm__ [__volatile__] ( assembler template : [output ...

  5. ARM汇编初探---汇编代码中都有哪几类指令---ARM伪指令介绍

    要学习一个东西首先要把概念搞清楚,以下仅仅是自己的一些关于汇编的理解. 可运行文件里的01码是机器码,机器码不等于汇编码,尽管机器码能够非常easy翻译成汇编码. 汇编码中包括非常多汇编指令.伪指令和 ...

  6. 如何在C或C++代码中嵌入ARM汇编代码

    转载自:http://blog.csdn.net/roland_sun/article/details/42921131 大家知道,用C或者C++等高级语言编写的程序,会被编译器编译成最终的机器指令. ...

  7. 生成ARM汇编

    使用ndk即可生成arm汇编 1.首先写好hello.c 2.编写makefile #ndk根目录 NDK_ROOT=E:\Android\android-ndk-r10b #编译器根目录 TOOLC ...

  8. ARM汇编指令调试方法

    学习ARM汇编时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在 ...

  9. ARM汇编

    ARM汇编 ISA ISA即指指令集架构(Instruction Set Architecture)是与程序设计有关的计算机架构的一部分,包括本地数据类型.指令.寄存器.地址模式.内存架构.中断和意外 ...

随机推荐

  1. 重新看《JavaScript高级程序设计》

    几点心得: 1)数据是基础,一共有3种基础数据:null.undefined.和object:遵循从无到有从简单到复杂的演变过程 2)衍生数据:衍生数据是指操作符合语句,这些是基础数据产生导致的必然结 ...

  2. centos7 下pycharm无法输入中文问题解决方案

    作者使用的pycharm是2017.2 在pycharm.sh脚本的如下行(大约在201行): # -------------------------------------------------- ...

  3. 关于c++中public & private方法调用问题

    class IDNoIdentifier { public: IDNoIdentifier(); ~IDNoIdentifier(); typedef vector<cv::Rect> C ...

  4. Angular-Cli中引用第三方库

    最近在学习angular(AngularJS 2),根据教程使用angular-cli新建项目, 然而在添加JQuery和Bootstrap第三方库时遇到了问题... 初试 我最初的想法是直接将相对路 ...

  5. 【Python】Python中的列表操作

    Python的列表操作可谓是功能强大且方便(相对于Java)简单.常规的操作就不说了(这不是一个入门教程),介绍几个很有特点的例子 添加 # 追加到结尾(append) li = [1, 2, 3, ...

  6. C# Socket服务端与客户端通信(包含大文件的断点传输)

    步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收 ...

  7. java 注解使用笔记

    一.语法 注解也属于一种类型 public @interface MyTestAnnotation { } 用@interface描述 根据情况可以应用于包.类型.构造方法.方法.成员变量.参数及本地 ...

  8. [LOJ 6000]搭配飞行员

    link 其实就是一道二分图匹配板子,我们建立$S$,$T$为源点与汇点,然后分别将$S$连向所有正驾驶员,边权为$1$,然后将副驾驶员与$T$相连,边权为$1$,将数据中给出的$(a,b)$,将$a ...

  9. X day2

    题目 官方题解 T1: 我们可以把问题化简为$a\times b \times c \leq n $中的有序$(a,b,c)$有多少组.分三种情况考虑 当$a=b=c$时,答案十分好统计 当$a< ...

  10. 手动实现一个简易版SpringMvc

    版权声明:本篇博客大部分代码引用于公众号:java团长,我只是在作者基础上稍微修改一些内容,内容仅供学习与参考 前言:目前mvc框架经过大浪淘沙,由最初的struts1到struts2,到目前的主流框 ...