指令和伪指令的区别及作用

本文介绍了指令和伪指令的概念及区别。指令是程序汇编翻译时可执行的语句,由汇编器翻译成机器语言字节,运行时由CPU加载执行,依赖CPU等设备实现功能。伪指令不是真正的指令,用于指示汇编程序如何汇编源程序,其功能在汇编时由汇编程序完成,只为编译服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 指令:是一种语句,它在程序汇编翻译时变得可执行,汇编器将其翻译成机器语言字节,并且在运行时由CPU加载和执行每一条指令语句表示CPU具有的一个基本能力,比如数据传送,两数相加或相减,移位等,而这种能力是在目标程序运行时完成的,是依赖于CPU、存储器、IO等接口设备来实现的。

  • 伪指令:顾名思义,它不是真正的指令,也就是不是最终的指令,是用于指示汇编程序如何汇编源程序,所以这种语句又叫命令语句,例如伪指令告诉汇编程序,该源程序如何分段,有哪些逻辑段在程序段中,哪些是当前段等等,伪指令语句的这些命令功能是由汇编程序在汇编源程序时,通过执行另外一段程序来完成的,而不是在运行目标程序时实现的。

  • 通俗地讲:
    就好像召开新闻发布会,主持人用中文讲话,由一个翻译,现场翻译成英文,讲给外国记者听。
    主持人说的中文,大部分都是要翻译成英文的;少数几句,是说给翻译听的,告诉他如何翻译。

  • 我们写的指令,由“编译软件”翻译成机器码的,称为指令语句;有一些是写给“编译软件”看的,不翻译成机器码,这样的就是“伪指令”。

    • 翻译人员—>编译软件
      大部分中文化—>指令 是给外国记者听的
      少部分中文话—>伪指令 是给翻听的
  • 总结:指令是控制程序运行时的机器代码运作的,是CPU执行的依据,编程、编译、执行都是有效的。

  • 伪指令不直接控制运行时刻的机器,但是控制翻译程序如何生成机器指令代码,也就是只为编译服务,编译完成后,伪 指令的作用也就消失了。

参考:猪哥-嵌入式的博客
baidu_知道的博客

<think>嗯,用户问的是LDR伪指令ADR伪指令区别用法。首先我需要回忆一下ARM汇编里的这两个指令。根据之前提供的引用,ADR是小范围的地址加载指令,基于PC或寄存器的相对偏移,而LDR伪指令则是加载绝对地址或大范围的地址。 用户可能是在学习嵌入式系统或者底层编程,遇到地址加载的问题。他们可能想知道在什么情况下使用哪一个指令,以及为什么有时候ADR有效,而LDR不行,或者反过来。 需要区分伪指令实际指令区别。ADR是伪指令,会被编译器替换为ADD或SUB指令,而LDR伪指令可能被替换为MOV或者其他加载指令。另外,地址相关无关的代码也是一个重点。ADR是位置无关的,因为它使用相对偏移,而LDR伪指令是位置相关的,因为它加载的是绝对地址,这在链接时就确定了。 还要考虑MMU开启前后的情况。开启前,物理地址链接地址可能不同,ADR能正确获取运行时地址,而LDR伪指令得到的是链接地址,可能不正确。开启MMU后,虚拟地址链接地址一致,两者都能正确工作。 另外,应用场景方面,ADR适合小范围的地址加载,比如同一代码段内的标签,而LDR伪指令适合加载大范围的地址或绝对地址,比如外设寄存器地址。 需要结合引用中的例子,比如在启动MMU前后的不同表现,来说明两者的区别。还要提到使用限制,比如偏移范围,ADR的偏移量有限,超过的话编译器会报错,而LDR伪指令可以处理更大的地址。 最后,总结他们的主要区别:地址生成方式(相对 vs 绝对)、地址空间依赖、应用场景,以及位置相关性的不同。</think>### LDR伪指令与ADR伪指令区别及用法 #### 一、核心区别 1. **地址生成方式** - **ADR**:通过`PC相对偏移`计算地址,生成的是运行时实际物理地址或相对地址,属于位置无关码[^1][^3] 公式:$$ Rd = PC \pm offset $$ - **LDR伪指令**:直接读取链接时确定的绝对地址,属于位置相关码[^2][^4] 公式:$$ Rd = [Label\_address] $$ 2. **地址空间依赖** - **ADR**在MMU未开启时(物理地址空间)可正确获取标签的实际物理地址 - **LDR伪指令**在MMU开启后(虚拟地址空间)才能正确匹配链接地址[^3] #### 二、执行效果对比 | 场景 | ADR结果 | LDR伪指令结果 | |--------------------|----------------------|---------------------| | MMU关闭(物理地址空间) | 实际物理地址 (如0x60008000) | 链接地址 (如0x80008000) | | MMU开启(虚拟地址空间) | 有效虚拟地址 | 有效虚拟地址 | **案例**: ```armasm _start: adr r0, stext @ 转换为 add r0, pc, #offset ldr r1, =stext @ 转换为 ldr r1, [pc, #offset_to_stext_data] ``` #### 三、应用场景 1. **ADR适用场景** - 需要位置无关的代码(如Bootloader、内核初始化阶段) - 短距离地址跳转(偏移量限制±4095字节)[^1][^3] - 动态获取运行时地址(如MMU未开启时的物理地址计算) 2. **LDR伪指令适用场景** - 加载绝对地址或大范围偏移地址(如外设寄存器地址) - 需要精确匹配链接脚本定义的符号地址[^2][^4] - 加载32位立即数(当值超出MOV指令范围时) #### 四、编译实现差异 1. **ADR** 被编译器转换为`ADD/SUB`指令,仅占用1条指令空间 ```armasm adr r3, label => add r3, pc, #0x20 ``` 2. **LDR伪指令** 生成`文字池(literal pool)`存储绝对地址,需占用额外内存空间[^4] ```armasm ldr r0, =0xFD800000 => ldr r0, [pc, #offset] ... .word 0xFD800000 ``` #### 五、关键限制 1. **ADR偏移范围** 最大支持±4095字节偏移(ARM模式),超出范围需改用LDR伪指令[^1] 2. **LDR伪指令可靠性** 在地址重映射场景下,必须确保MMU已正确配置虚拟地址映射[^3]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值