ldr指令什么意思(ldr指令是什么意思)

ldr指令什么意思(ldr指令是什么意思)span id contentlabel style font size 14px LDR 指令与 LDR strong 伪指令 strong 的 4 种形式 p LDR R0 R1 指令 将 R1 指向的内存地址存放的内容加载到 R0 中 p 本文引用地址 https span

大家好,我是讯享网,很高兴认识大家。




讯享网

		<span id="contentlabels" style="font-size:14px;">LDR指令与LDR<strong>伪指令</strong>的4种形式:<p>LDR R0,[R1]:指令,将R1指向的内存地址存放的内容加载到R0中;</p>本文引用地址:https://www.eepw.com.cn/article/201611/317563.htm<p>LDR R0,LABEL:指令,将标号LABEL所代表的内存地址处存放的内容加载到R0中;</p><p>LDR R0,=10000:伪指令,将常熟10000赋予R0,采用LDR指令+文字池的方式实现;</p><p>LDR R0,=LABEL:伪指令,将标号LABEL所代表的内存地址赋予R0;</p><p></p><p>指令部分:</p><p></p><p><strong>伪操作</strong>部分:</p><p>符号定义伪操作:定义变量,对变量进行赋值,定义寄存器名称</p><p>GBLA:全局的算术变量,初始化为0;</p><p>GBLL:全局的逻辑变量,初始化为{FALSE};</p><p>GBLS:全局的串变量,初始化为&ldquo;&rdquo;;</p><p></p><p>LCLA:局部的算术变量,初始化为0;</p><p>LCLL:局部的逻辑变量,初始化为{FALSE};</p><p>LCLS:局部的串变量,初始化为&ldquo;&rdquo;;</p><p></p><p>SETA:给算术变量赋值;</p><p>SETL:给逻辑变量赋值;</p><p>SETS:给串变量赋值;</p><p></p><p>RLIST:为一个通用寄存器列表定义名称;</p><p>CN:为一个协处理器的寄存器定义名称;</p><p>CP:为一个协处理器定义名称;</p><p>DN:为一个双精度的VFP寄存器定义名称;</p><p>SN:为一个单精度的VFP寄存器定义名称;</p><p>FN:为一个FPA浮点寄存器定义名称;</p><p></p><p>数据定义伪操作</p><p>LTORG:声明一个数据缓冲池的开始;</p><p>MAP:定义一个结构化的内存表的首地址,同义词为^;</p><p>FIELD:定义一个结构化内存表中的数据域,同义词#;</p><p>SPACE:分配一块内存单元,并用0初始化,同义词%;</p><p>{label} SPACE exprexpr表示分配的内存字节数;</p><p></p><p>DCB:分配一段字节内存单元,并用expr初始化之,同义词=;</p><p>{label} DCB expr, {expr}...expr是-128~255的数值或字符串;</p><p></p><p>DCD,DCDU:分配一段字内存单元,分配的内存都是字对齐的,并用expr初始化之,同义词&,DCDU分配的内存单元不严格字对齐;</p><p>DCDO:分配一段字内存单元,分配的内存都是字对齐的,并将每个字单元的内容初始化为expr标号基于静态基址寄存器R9的偏移量;</p><p>DCFD,DCFDU:</p><p>DCFS,DCFSU:</p><p>DCI:(<strong>ARM</strong>)分配一段字内存单元,分配的内存都是字对齐的,并用expr初始化;(Thumb)分配一段半字内存单元,分配的内存都是半字对齐的,并用expr初始化;</p><p>DCQ,DCQU:</p><p>DCW,DCWU:</p><p></p><p>汇编控制伪操作</p><p>IF,ELSE,ENDIF:根据条件将一段源代码包括在<strong>汇编语言</strong>程序中或者将其排除在程序之外;</p><p>IF logical expression</p><p>instructions or directives</p><p>ELSE</p><p>instructions or directives</p><p>ENDIF</p><p></p><p>WHILE,WEND:根据条件重复汇编相同的或者几乎相同的一段源代码;</p><p>WHILE logical expression</p><p>instructions or directives</p><p>WEND</p><p></p><p>MACRO,MEND:定义宏定义体;</p><p>MEXIT:从宏中跳转出去;</p><p></p><p>栈中数据帧描述伪操作;</p><p></p><p>信息报告伪操作;</p><p></p><p>其它伪操作:</p><p>CODE16,CODE32:</p><p>EQU:为数字常量,基于寄存器的值和程序中的标号定义一个字符名称,同义词*;</p><p>name EQU expr {, type}</p><p></p><p>AREA:</p><p>ENTRY:</p><p>END:</p><p>ALIGN:</p><p>EXPORT:</p><p>GLOBAL:</p><p>IMPORT:</p><p>EXTERN:</p><p>GET:</p><p>INCLUDE:</p><p>INCBIN:</p><p>KEEP:</p><p>NOFP:</p><p>REQUIRE:</p><p>REQUIRE8:</p><p>PRESERVE8:</p><p>RN:</p><p>ROUT:</p><p></p><p>伪指令部分:伪指令不是真正的指令,在汇编编译器对源程序进行汇编处理时被替换成对应的ARM或者Thumb指令;</p><p>ADR(小范围的地址读取伪指令):将基于PC的地址值或者基于寄存器的地址值读取到寄存器中;</p><p>ADR{cond} register, expr</p><p>expr是基于PC或者基于寄存器的地址表达式,取值范围如下:</p><p>地址值不是字对齐时,取值范围-255~255;</p><p>地址值是字对齐时,取值范围-1020~1020;</p><p>地址值是16字节对齐时,取值范围更大;</p><p></p><p>ADRL(中等范围的地址读取伪指令):将基于PC的地址值或者基于寄存器的地址值读取到寄存器中;</p><p>ADRL{cond} register, expr</p><p>expr是基于PC或者基于寄存器的地址表达式,取值范围如下:</p><p>地址不是字对齐时,-64KB~64KB;</p><p>地址是字对齐时,-256KB~256KB;</p><p>地址是16字节对齐时,取值范围更大;</p><p></p><p>LDR:将一个32位的常数或者一个地址值读取到寄存器中;</p><p>LDR{cond} register, ={expr | label-expr}</p><p>expr为32位常量;</p><p>label-expr为基于PC的地址表达式或者外部表达式;</p><p></p><p>NOP:汇编时被替换成ARM中的空操作;</p><p></p><p>实例程序:</p><p>1、</p><p>AREA LDR_Code, CODE, READONLY<br />ENTRY<br /><br />LDR r0, =src<br />LDR r1, =dst<br />MOV r2, r0<br />MOV r3, r1<br />MOV r5, #100<br />LDR r6, =100<br />LDR r7, =999999<br /><br /><br /><br /><br />srcDCD 0, 1;, 2, 3, 4, 5, 6, 7, 8, 9<br />dstDCD 0, 0;, 0, 0, 0, 0, 0, 0, 0, 0<br /><br /><br />END</p><p></p><p>反汇编代码:</p><p>  $a<br />  LDR_Code<br />    0x00000000:  e59f0024  $...  LDR   r0,0x2c<br />    0x00000004:  e59f1024  $...  LDR   r1,0x30<br />    0x00000008:  e1a02000  . ..  MOV   r2,r0<br />    0x0000000c:  e1a03001  .0..  MOV   r3,r1<br />    0x00000010:  e3a05064  dP..  MOV   r5,#0x64<br />    0x00000014:  e3a06064  d`..  MOV   r6,#0x64<br />    0x00000018:  e59f7014  .p..  LDR   r7,0x34<br />  src<br />  $d<br />    0x0000001c:  00000000  ....  DCD  0<br />    0x00000020:  00000001  ....  DCD  1<br />  dst<br />    0x00000024:  00000000  ....  DCD  0<br />    0x00000028:  00000000  ....  DCD  0<br />    0x0000002c:  0000001c  ....  DCD  28<br />    0x00000030:  00000024  $...  DCD  36<br />    0x00000034:  000f423f  ?B..  DCD  999999</p><p></p><p>(1)为LDR伪指令生成的代码,似乎有问题,不是基于PC的值,还是有默认的规则?</p><p>使用GNU ARM Assembly将上面的代码重新实现一次:</p><p>.section .text<br />.global _start<br />_start:<br />    LDR r0, =src<br />    LDR r1, =dst<br />    LDR r2, =1000<br />    LDR r3, =5555<br /><br /><br />    MOV r4, r2<br />    MOV r5, r3<br /><br /><br />.section .data<br />src: .word 0, 0<br />dst: .word 0, 1</p><p>编译通过了,不确定代码有没有问题,后面再检查</p><p>将上面的代码使用<strong>arm</strong>-none-eabi-as编译不链接,然后使用arm-none-eabi-objdump反汇编:</p><p>Disassembly of section .text:<br /><br /><br />00000000 <_start>:<br /> 0:  e59f0010    ldr   r0, [pc, #16]  ; 18 <_start+0x18><br /> 4:  e59f1010    ldr   r1, [pc, #16]  ; 1c <_start+0x1c><br /> 8:  e3a02ffa    mov   r2, #1000    ; 0x3e8<br /> c:  e59f300c    ldr   r3, [pc, #12]  ; 20 <_start+0x20><br /> 10:  e1a04002    mov   r4, r2<br /> 14:  e1a05003    mov   r5, r3<br /> 18:  00000000    andeq  r0, r0, r0<br /> 1c:  00000008    andeq  r0, r0, r8<br /> 20:  000015b3    strheq r1, [r0], -r3</p><p>诚如文档中对LDR的介绍:</p><p>    LDR r0, =src<br />    LDR r1, =dst<br />    LDR r2, =1000<br />    LDR r3, =5555</p><p>这四条命令都进行了处理,以LDR r0, =src为例:</p><p>0:  e59f0010    ldr   r0, [pc, #16]  ; 18 <_start+0x18></p><p>src的值被存储,ldr指令将[pc, #16]地址中的值加载到寄存器r0中,</p><p>ARM处理器中,pc的值为当前执行的指令的地址值加上8,因此,执行该条</p><p>指令时,pc的值为8,此时pc加上16,则为十进制的24,十六进制的</p><p>0x18,但是此时地址单元0x18中存储的却是一条指令:</p><p>andeq  r0, r0, r0</p><p>为什么?</p><p></p><p>将之前编译生成的.o文件使用arm-none-eabi-ld进行连接,生成可执行文件,</p><p>然后反汇编,此时代码变为:</p><p>Disassembly of section .text:<br /><br /><br />00008000 <_start>:<br />  8000:    e59f0010    ldr   r0, [pc, #16]  ; 8018 <_start+0x18><br />  8004:    e59f1010    ldr   r1, [pc, #16]  ; 801c <_start+0x1c><br />  8008:    e3a02ffa    mov   r2, #1000    ; 0x3e8<br />  800c:    e59f300c    ldr   r3, [pc, #12]  ; 8020 <_start+0x20><br />  8010:    e1a04002    mov   r4, r2<br />  8014:    e1a05003    mov   r5, r3</p><p><br />  8018:    00010024    andeq  r0, r1, r4, lsr #32<br />  801c:    0001002c    andeq  r0, r1, ip, lsr #32<br />  8020:    000015b3    strheq r1, [r0], -r3</p><p>此时,src的值应该存放在0x8000 + 8 + 16,8和16都是十进制的,因此应该是0x8018,</p><p>但是0x8018地址单元中为:</p><p>andeq  r0, r1, r4, lsr #32</p><p>lsr在上一篇寻址方式中有所介绍,此时r4中的值通过上面的指令可知为十进制的1000,十六进制的0x3E8,</p><p>0x3E8的二进制:</p><p>0000 0000 0000 0000 0000 0011 1110 1000,执行lsr #32操作,右移32位,则变为0,</p><p>r1中此时不管是什么值,AND指令执行按位取与操作,指令的执行结果自然是0,存放到r0寄存器中?</p><p>此处应该是个pool?为什么是指令?</p><p></p><p>(2)$a、$d分别表示什么意思?</p><p>摘录自:Using asThegnuAssembler的Mapping Symbols章节</p><p>The ARM ELF specification r<strong>equ</strong>ires that special symbols be inserted into object files to<br />mark certain features:<br />$a At the start of a region of code containing ARM instructions.<br />$t At the start of a region of code containing THUMB instructions.<br />$d At the start of a region of data.</p><p></p><p>待补充...</p></span>

讯享网
小讯
上一篇 2025-05-09 19:39
下一篇 2025-06-15 10:11

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/153050.html