对于一个大的文件,为了便于管理,一个好的办法时把一个大文件分为若干个小文件,每个小文件包含一部分相关的功能,这样功能将显得很整洁,而且移植到其它工程的时候也很方便,把文件copy过去即可。
  对于汇编,我们也许知道,可以使用orgxxxx来指定函数的地址(org是一个段内指定偏移的伪指令),但是当指定这个地址时,是否与其它函数冲突呢?有可能其它函数过长已经占用了这个地址。难道要数手指计算函数的长度吗?另一个问题是主函数怎样调用被调函数呢?
  在回答这些问题之前,先来看看使用的开发工具是怎样工作的。首先A51汇编器汇编文件后会生成.obj文件,这并不是最终需要的文件。通常还要使用一个叫链接器(如BL51)的工具,把多个obj文件组合起来,生成最终的二进制代码文件(或其它格式的文件)。虽然传递给链接器的参数是一个或多个obj文件,但是链接器在链接时却是按段来计算的。每个obj文件里包含的都是一些绝对地址段或可重定位段链接器必须为可重定位段重新计算及分配地址,并计算绝对地址段是否重叠。因此:可重定位段可以保证多目标文件链接时不发生目标地址重叠,故绝对地址段只适用用某些特殊场合,如固定I/O口或中断向量的入口地址。绝对地址段就是这个段的地址在传入链接器的时候已经固定,链接器不能改变这个段的地址。可重定位段就是这个段的地址需要链接器分配,如是代码段的段内的跳转等指令的偏移也需要重新进算。
  段的另一种分法可分为代码段、数据段。数据段又分为以初始化数据段和未初始化数据段。这里不细说。
  通过上面可知,如果一个函数是一个段,而这个段是可重定位的,那么就可以不用考虑代码的地址问题了,把这个问题留给了链接器。剩下来的问题就是怎样把一个函数变为一个段的问题,(当然一个段可包括很多函数,在汇编中,函数只是一个说法而已)。大部分的汇编器都会提供伪指令来定义绝对段及可重定位段(写法上有可能有区别而已)。

  在A51中,定义段的伪指令是
cseg -- 绝对代码段
bseg -- 绝对位段
dseg -- 绝对内部直接寻址(data)数据段
iseg  -- 绝对内部间接寻址(idata)数据段
xseg -- 绝对外部(xdata)数据段

segment -- 定义一个可重定位段
rseg -- 选择一个可重定位段

使用说明:

  1. NAME 模块名 //用来指明当前程序模块
  2. 重定位段名 SEGMENT 段类型 [重定位类型]  //重定位类型为可选, 

  段类型为可用的段类型有CODE、DATA、XDATA、IDATA、BIT。重定位类型为PAGE、INPAGE、INBLOCK、BITADDRESSABLE、UNIT、OVERLAYABLE。段名等价于段符号,在表达式中用段名表示复合段中的基地址。

  每个函数都包含在一个段内。org 0 改为了 cseg at 0, org 50h则被删除,这样链接程序会自动的为每个重定位段分配地址,也就相当于为函数分配的地址,这样函数与函数之间就没有了gas(^_^,这是Keil的术语,也就相当于空隙),当有gas时,程序是没有使用的,白白浪费了。对于51这样的系统可重定位段的另一个好处就是空间覆盖处理,这将在下一节细说。

  也许读者会有这样的疑问,之前的示例并没有定义任何的段,它们工作得也很好啊,那汇编器及链接器是怎么工作的呢?链接器的工作仍然是不变的,只是汇编器在扫描文件时发现文件没有定义段,会为每个空间分配一个绝对段,地址从0开始。以code空间为例,如果没有定义段,则默认段从0开始,这时文件中的第一条指令的地址就是0开始,而org伪指令是指定段内偏移的,这里的org 0有没有也就无所谓了。不信读者可以把这条语句去掉再汇编一次。

  而当工程里开始,这时链接器就会提示地址空间重叠。因此可重定位段的用处就在于此:它不会造成地址空间重叠。

  下面将介绍的几个伪指令对于多文档工作就特别的有用了。
extrn  -- 指示符号是外部的,并告诉模块是什么类型
extern -- 跟extrn差不多,相当于extrn的一种特例
public -- 指示符号可在其它模块使用

使用方法如下:
EXTRN class (symbol [ , symbol ... ])
EXTRN class:type (symbol [ , symbol ... ])

EXTERN class:type (symbol [ , symbol ... ])

PUBLIC symbol [ , symbol ... ]

中括号内是可选部分。

  C51编译器采用了一个扩展关键字reentrant作为定义函数时的选项,需要将一个函数定义为可重入函数时,只要在函数后面加上关键字reentrant即可

  与非可重入函数的参数传递和局部变量的存储分配方法不同,C51编译器为可重入函数生成一个模拟栈(相对于系统堆栈或是硬件堆栈来说),通过这个模拟栈来完成参数传递和存放局部变量。模拟栈以全局变量?C_IBP、?C_PBP和?C_XBP作为栈指针(系统堆栈栈顶指针为SP),这些变量定义在DATA地址空间,并且可在文件startup.a51中进行初始化。根据编译时采用的存储器模式,模拟栈区可位于内部(IDATA)或外部(PDATA或XDATA)存储器中。如表1所示:

存储模式

栈指针

栈区域

Small

?C_IBP(1  字节)

间接访问的内部数据存储器(IDATA),栈区最大为256字节

Compact

?C_PBP(1字节)

分页寻址的外部数据存储器(PDATA),栈区最大为256字节

Large

?C_XBP(2字节)

外部数据存储器(XDATA),栈区最大为64K

  表1注意:51系列单片机的系统堆栈(也叫硬件堆栈或常规栈)总是位于内部数据存储器中(SP为 8位寄存器,只能指向内部),而且是“向上生长”型的(从低地址向高地址),而模拟栈是“向下生长”型的。

Keil的可重定位段的更多相关文章

  1. Oracle-在线重定义操作文档

    Oracle-在线重定义操作文档 2015年10月8日 15:51 在线重定义的大致操作流程如下: (1)创建基础表A,如果存在,就不需要操作. (2)创建临时的分区表B. (3)开始重定义,将基表A ...

  2. 11 Servlet_03 关键字总结 资源跳转:重定项 键值对 继承类 do-get do-post Request域 Context域 =空针解决方法

    知识点总结: 1.java里的关键字: byte short int long  数据类型 (正整数)char  数据类型(单字符型)boolesn ture false  布尔类型float dou ...

  3. C语言中输入输出重定,freopen()妙用。

    使用的理由(范围):如果输入数据很庞大,需要一次又一次的重新输入和调试时可采用本函数. freopen ()函数: 1.格式 FILE * freopen ( const char * filenam ...

  4. 关于Servlet中的转发和重定项

    一:转发 首先转发属于服务器内部行为,通过浏览器的地址栏是看不到URL变化的.比如说客户端发送一个请求到ServletA,ServletA接收到请求,但是没有能力处理,但是ServletA知道Serv ...

  5. java:JSP(JSPWeb.xml的配置,动态和静态导入JSP文件,重定项和请求转发,使用JSP实现数据库的增删改查实例)

    1.JSP的配置: <%@ page language="java" import="java.util.*" pageEncoding="UT ...

  6. 《windows核心编程系列》二十一谈谈基址重定位和模块绑定

    每个DLL和可执行文件都有一个首选基地址.它表示该模块被映射到进程地址空间时最佳的内存地址.在构建可执行文件时,默认情况下链接器会将它的首选基地址设为0x400000.对于DLL来说,链接器会将它的首 ...

  7. 原创 C++应用程序在Windows下的编译、链接:第一部分 概述

    本文是对C++应用程序在Windows下的编译.链接的深入理解和分析,文章的目录如下: 我们先看第一章概述部分. 1概述 1.1编译工具简介 cl.exe是windows平台下的编译器,link.ex ...

  8. Android 6.0 新功能及主要 API 变更

    运行时权限 这个版本中引入了新的权限模型,现在用户可以在运行时直接管理应用程序的权限.这个模型基于用户对权限控制的更多可见性,同时为应用程序的开发者提供更流畅的应用安装和自动升级.用户可以为已安装的每 ...

  9. 第20章 DLL高级技术(3)

    20.4 函数转发器 (1)函数转发器原理(下图是利用Dependency Walker打开Kernel32.dll得到) ①图中CloseThreadpool*等4个函数转发到NTDLL中相应的函数 ...

随机推荐

  1. 《SDN核心技术剖析和实战指南》第一章小结

    第一章主要是概况.新技术有一个特点是,每家都有不同的说法.这里我只说说我比较认同的部分. SDN的核心概念大概有两个:转发面与控制面分离.开发可编程化.书里还说逻辑上集中控制,其实这个就可以从转发与控 ...

  2. 玩转docker

    开篇先论赌 (组词,赌博,....),时刻,每天都在赌! 何为赌?仁者见仁,智者必定又有一番见解,保持沉默,意见保留; ——改变思维模式,Ruiy让赌赢在“思维”!!!; 存在在IT界Ruiy定格,即 ...

  3. vb安装过程中 ntvdm.exe[9696]中发生未处理的win32异常

    最近电脑总是出问题导致我的学习效率很低,前几天在用VB6.0的时候有个知识点不太熟悉,于是按F1发现不会出来帮助文档.突然想到重新装系统之后忘记了安装MSDN帮助插件,就在我安装这个软件的时候发现电脑 ...

  4. linux中cat、more、less、tail、head命令

    cat命令功能用于显示整个文件的内容单独使用没有翻页功能因此经常和more命令搭配使用,cat命令还有就是将数个文件合并成一个文件的功能. more命令功能:让画面在显示满一页时暂停,此时可按空格健继 ...

  5. JAVA二维数组小记

    入手JAVA第二天 //二维数组 //数据类型 [][] 数组名 = new 数据类型[行的个数][列的个数];3 String [][] name = {{"admin",&qu ...

  6. pptv web前端面试题答案

    这是星期一考完试,答应星期三补上的,代码很简单,就不写注释了 //php快排 function quickSort(&$arr){   $arr_left=new array();   $ar ...

  7. 将16进制颜色转换成UIColor-ios

    -(UIColor *) hexStringToColor: (NSString *) stringToConvert { NSString *cString = [[stringToConvert ...

  8. (1)QlikView概要

    本文的内容,以学习的两个合伙人: I.什么是Qlikview II. QlikView 的优点和缺点 1.1什么是QlikView 1.1什么是QlikView QlikView是一个工具,一个商业智 ...

  9. DES加解密算法Qt实现

      算法解密qt加密table64bit [声明] (1) 本文源码 大部分源码来自:DES算法代码.在此基础上,利用Qt编程进行了改写,实现了DES加解密算法,并添加了文件加解密功能.在此对署名为b ...

  10. [编译原理代码][NFA转DFA并最小化DFA并使用DFA进行词法分析]

    #include <iostream> #include <vector> #include <cstring> #include "stack" ...