关于加载地址和运行地址理解

25 篇文章 0 订阅
14 篇文章 0 订阅

这几天在看uboot的汇编部分,唯一觉得有点弄不懂的就是存储地址和运行地址了,网上看了很多文章,最后还是没有完全通透,云里雾里的,昨晚看了这篇帖子突然恍然大悟,特来谈谈个人的想法,不对的地方还请朋友们帮忙指出来,以便修正,谢谢_

加载地址/存储地址和运行地址/链接地址区别:
a.加载地址是指代码存储所在的物理地址,由于ARM总是从0开始取值,即PC初始值为0,所以加载地址必须对应0地址,程序才能正确启动执行,之后才可以进行跳转,比如设置PC等于一个子程序的入口地址,而这个入口地址可能在rom中也可能在ram中。
b.运行地址是链接器根据链接文件中指定的链接地址作为程序运行的起始地址,(作用)将程序中所有指令地址按照相对于这个起始地址的位置进行赋值,与程序实际运行时地址不一定相同,因为实际的程序运行起始地址总是0,而链接地址不一定为0,决定于程序需要在ROM还是RAM中运行);如果链接地址与加载地址设为相同,则所有寻址地址在ROM上都有对应的指令存在,也就可以正常执行;但如果链接地址与加载地址不同,则所有指令的地址是根据链接地址确定的,在ROM上不存在与之对应的代码入口(即使链接地址正好还处于ROM代码中,接下来执行的指令也将是不正确的和存在偏移的)
总的来说就是:加载地址是程序实际执行时的真实起始地址且必须为0;而链接地址的作用就是在链接过程中以链接地址为基准,确定程序中所有指令的相对位置,加载地址与链接地址相同时,该相对位置处才存在对应的指令,否则该相对位置处将不存在正确指令(uboot中存在特殊情况)所以加载地址与运行地址不同时的区别就是指令的寻址地址不同,而这个寻址地址只对位置相关指令如ldr起作用。
那么在程序中不就是根据指令地址来执行程序的吗,怎么有时候两者不同时程序也能正确执行?这就扯到了位置无关指令和位置相关指令,其实很容易理解:位置无关指的就是程序的实际运行地址(PC值)是根据之前的pc进行正负偏移得到的(比如b、bl指令)他不管代码被链接后指令所应该在的地址,这个偏移量在汇编时已经确定,不管程序当前位置处于rom还是ram,b指令总能得到下条指令的地址(绝对偏移)而继续执行;程序相关指的就是接下来的pc不是进行绝对偏移,而是进行相对偏移(比如ldr指令),也就是直接给pc赋一个相对值,这个值就是上面说的基于链接地址计算得到的指令的相对地址,那么问题就迎刃而解了——由上面推导可知:如果链接地址与加载地址不同,则pc得到的值与实际指令存放的地址就不是相同的,也就是该处没有有效的可执行指令,当然载入pc后程序也就会跑飞了。
问:将链接地址与加载地址刻意设为不同有什么作用?
答:如果所有代码都在ROM中执行,则链接地址必须设为加载地址0,除非你只用位置无关指令;而在嵌入式应用中,往往想要把程序加载到SDRAM中快速运行,但是碍于起始地址的影响,不可能直接达到这一步,所以思路就是:让程序加载地址等于rom起始地址,而链接地址等于ram中某一处的起始地址(暂且称为ram_start),所以在链接完成后所有指令的相对位置,程序先从ROM中启动,然后让代码中最前面内容实现代码的复制(ROM中程序->RAM中的ram_start处),并通过ldr指令(在这之前不应该使用位置相关指令给pc赋值!)将接下来要执行的指令的相对地址(在RAM范围内)赋给pc,程序就可以继续正确运行下去了。(b指令当然就没法用来跳转了)

下面来看几张图:
第一张为存储地址映射图
存储映射图
第二张为两次不同的链接地址所对应的反汇编
不同链接地址反汇编
第三张为代码重映射后存储映射图
重定位后示意图
第四张为程序运行流程示意图
运行示意图

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
加载运行预训练模型的步骤会根据使用的深度学习框架有所不同。下面是一个通用的示例代码,可以帮助您理解这个过程: 1. 导入所需的库和模块: ```python import tensorflow as tf from tensorflow.keras.applications import ResNet50 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions ``` 2. 加载预训练模型: ```python model = ResNet50(weights='imagenet') ``` 这里使用了ResNet50作为示例模型,您可以根据自己的需求选择其他预训练模型。`weights='imagenet'`参数将加载预训练的ImageNet权重。 3. 准备输入图像: ```python img_path = 'path/to/image.jpg' img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) x = preprocess_input(x) x = np.expand_dims(x, axis=0) ``` 确保将 `'path/to/image.jpg'` 替换为您实际图像文件的路径。在这个示例中,我们将图像的尺寸调整为(224,224),以符合ResNet50模型的输入要求。 4. 运行推理: ```python preds = model.predict(x) ``` 这将使用加载的预训练模型对输入图像进行推理,返回预测结果。 5. 解码预测结果: ```python decoded_preds = decode_predictions(preds, top=3)[0] for class_id, class_name, probability in decoded_preds: print(f"{class_name}: {probability:.4f}") ``` 这将使用预定义的`decode_predictions`函数对预测结果进行解码,并打印出前三个最高概率的类别和相应的概率。 请注意,这只是一个示例代码,实际使用时,您可能需要根据具体模型和数据进行一些调整。确保您已经安装了所需的库,并根据自己的需求对代码进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值