zoukankan      html  css  js  c++  java
  • 韦东山yy公开课笔记(2)--汇编,段,栈,重定位/链接地址,位置无关吗



    1. 要不要学习汇编
    可以只懂一点,工作中基本不用,一旦用就是出了大问题

    ldr : load 读内存
    ldr r0, [r1]  : r1里存放的是地址值, 去这个地址读取4字节的内容,存入r0

    str : stroe 写内存
    str r0, [r1]  : r1里存放的是地址值, 把r0里的4字节数据存入这个地址



    所有的汇编、C程序也好,终极目标就是:读写某个地址


    2. 程序为何要分为代码段、数据段、BSS段
    程序的指令等是只读的,可以把它们归为一类,以便运行时可以放在ROM等设备上,
    当然也可以放在内存,只不过这块内存无需写操作

    程序的全局变量等,是可读可写的,可以把它们归为一类,放在内存里

    假设程序里有1百万个初始值为0的全局变量,
    你最终编译出来的bin文件里要不要存放这1百万个0变量?
    肯定没那么傻,不存!
    怎么办?
    把它们归为一类,只记录它们的内存起始地址、结束地址。
    在程序运行之前,把这块内存全部清零



    3. 栈的作用
    3.1
    调用C函数之前要设置栈,
    因为在C函数的开头要保存某些值(比如返回地址), 这些值肯定要保存在内存里,
    这块内存大家约定用sp寄存器指明位置,
    这块内存就是栈

    3.2 用来保存局部变量



    4. 重定位/链接地址
    使用全局变量时,是根据它的地址去读写内存。
    这个地址跟链接脚本的起始地址密切相关
    也可以知道:
    要想正确访问到全局变量,程序运行之前应该位于它的链接地址上

    4.1 NAND启动时,NAND前4K会被自动复制到片内SRAM并运行
        如果程序远超过4K,那么前4K的代码应该把程序完全复制到SDRAM
        问:SDRAM那么大,应该复制到哪个位置呢?
        答:复制到它的链接地址去
            因为全局变量等是以链接地址来访问的,在程序运行之前,这个地址上应该有正确值


    由此也可以得到裸板框架:
    a. 必要的硬件初始化:看门狗、时钟、SDRAM
    b. 重定位: 把程序到FLASH上读到内存中它的链接地址处
    c. 清除BSS
    d. 调用C函数


    5. 位置无关码
    假设程序的链接地址是0x30000000,这是位于SDRAM上,
    一上电是从0地址开始执行
    问:为何0地址开始的那部分代码可以正确执行?
    答:它们是使用位置无关的代码编写的
        a. 不访问全局变量/静态变量
        b. 跳转时使用相对跳转指令b, bl

    test1:
                            b  test2  //如何实现跳转?
                                      b 当前值 + (test2 - test1)
    ....
    ....
    test2:                            


    参考<嵌入式LINUX应用开发完全手册> P38,<3.1.2 arm-linux-ld 选项>

  • 相关阅读:
    PAT (Basic Level) Practice (中文)1022 D进制的A+B
    PAT (Basic Level) Practice (中文)1001 害死人不偿命的(3n+1)猜想
    Pycharm的调试
    Pycharm自带Git实现版本管理
    JMeter分布式压测
    JMeter内存溢出:java.lang.OutOfMemoryError: Java heap space解决方法
    JMeter资源监控插件PerfMon的使用
    JMeter命令行执行+生成HTML报告
    JMeter压测“java.net.SocketException: Socket closed”解决方法
    JMeter压测“java.net.BindException: Address already in use: connect”解决方法
  • 原文地址:https://www.cnblogs.com/0822vaj/p/3972677.html
Copyright © 2011-2022 走看看