u-boot 中的汇编指令asr adrl ldr

来源:互联网 发布:amc分析知乎 编辑:程序博客网 时间:2024/05/20 01:33

adr,adrl和ldr指令的用法比较

(2011-01-02 13:54:50)
转载
标签:

it

 

ADR
    这是一条小范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。

    使用的格式:ADR register,exper。

    在编译源程序时,汇编器首先计算出当前PC到exper的偏移值#offset_to_exper,然后会用一条ADD或者SUB指令来替换这条伪指令,例如:ADD register,PC,#offset_to_exper。

    注意,标号exper与指令必须在同一代码段。
ADRL:
    这是一条中等范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。

    使用的格式:ADRL register,exper。

    在编译源程序时,汇编器会用两条合适的指令来替换这条伪指令。

    例如:

             ADD register,PC,offset1

             ADD register,register,offset2  

    与ADR相比,它能读取更大范围的地址。

    注意,标号exper与指令必须在同一代码段。
LDR:
   第一种情况:

        当LDR用做ARM指令时,它将基于PC的相对偏移地址处存储的值读到目标寄存器中。

        应用格式:LDR register,[expr]
   第二种情况:

         当LDR用做ARM伪指令时,它用于大范围的地址读取。

         其实说它用于大范围的读取,还不如说它用于大范围的地址赋值。我们来看一下这条伪指令的应用格式:LDR register,=expr/label_expr ,显然,我们可以直观的看出,指令的目的就是要将expr或label_expr赋值(=)给register.所以在编译时,当expr或label_expr的值没有超出MOV和MVN的范围时,采用MOV或MVN指令来代替这条伪指令就显得理所当然了。当expr或label_expr的值超出MOV和MVN的范围时,汇编器将expr或label_expr放入文字池中,并使用一条程序相对偏移指令LDR从文字池读出常量。例如:LDR register,[PC,#offset to literal pool]

***********************************************************************************

B 是最简单的分支。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的地址,从那里继续执行。BNE指令,是个条件跳转,即:是“不相等(或不为0)跳转指令”。如果不为0就跳转到后面指定的地址,继续执行


*******************************************************************************

汇编中.word的具体用途是什么?  

2011-03-09 12:49:58|  分类: 默认分类 |  标签: |字号 订阅

_undefined_instruction: .word undefined_instruction 
_undefined_instruction是一个标号,处理到这里时,asm会把undefined_instruction的值按16bit的形式放在此标号处。 
ldr pc, _undefined_instruction 
就是从_undefined_instruction处取值,即undefined_instruction, 并设置到pc中。

.word就是在这个地方放一个值。相当于在这里定义一个数据变量。用.word定义了一个16bit的数据。

并将underfined_instruction的值本身放在这里,因此,pc=undefined_instruction,实现跳转。 
ldr 是把数据从存储器传输到寄存器上,格式如下: 
ldr(条件) 目的寄存器,<存储器地址>

转帖:

ldr r1, _rWTCON 
_rWTCON: 
.word 0x15300000 
这两个语句是不是说把地址0x1530 0000 上的内容传递到r1? 而不是把0x1530 0000 放到r1 ? 
不是把地址0x1530 0000 上的内容传递到r1,是把地址_rWTCON上的内容放到r1,而地址_rWTCON上的内容是0x15300000。实际上就是把r1设置为0x15300000 
------------------------------------------ 
.word和0x1530 0000有什么关系?.word就是把expression上的值取出来? expression代表地址? 
.word expression就是在当前位置放一个word型的值,这个值就是expression 
举例来说, 
_rWTCON: 
.word 0x15300000 
就是在当前地址,即_rWTCON处放一个值0x15300000 
翻译成intel的汇编语句就是: 
_rWTCON dw 0x15300000没有.long/.word 
汇编程序就不知道你想在这里放一个多大的数据, 
相当于数据类型。

另外还应注意:在arm7,9中(其他的我不清楚)arm指令集中一个字类型就是32位。

附:

uboot Stage1阅读的一些心得

 感觉一定要理解一些基本的概念,然后在看懂汇编的基础上,再分析uboot的流程。

1.关于汇编的语法

这里有两套汇编的语法:分为ARM公司的标准ARM汇编语言和GNU对ARM支持的GNU  ARM汇编。ARM标准汇编语言即ARM公司的开发工具ADS里用的汇编语言;GNU汇编即在LINUX下用GCC编译的汇编。两者语法有少许差异。因此,通常我们下载的LINUX下的ARM接口代码放到ADS下是不能编译通过的,需要进行少许修改。

GNU AS语法即AT&T汇编语法,uboot用到的语法。

2.标签的含义

As代码 复制代码 收藏代码
  1. .globl _start   
  2.   
  3. _start: b       reset

  标签就是在某行程序代码前作一个标记,标签代表的是这行代码的地址。

As代码 复制代码 收藏代码
  1. .globl _armboot_start   
  2.   
  3. _armboot_start:   
  4.        
  5. .word _start   

.word expression就是在当前位置放一个word型的值,这个值就是expression ,此处的含义就是建立一个全局标签_armboot_start,在这个位置上放置_start的值(可以这样理解,_armboot_start是一个地址,这个地址中的内容是_start),则下面的语句会把地址_armboot_start处的内容(_start)装载到r2中。

As代码 复制代码 收藏代码
  1. ldr r2, _armboot_start  
  这样做的目的是因为LDR指令的格式为:LDR{条件}    Rd, <地址>。

3..word 0x0badc0de

含义:保留一个字,初始化一下。实际的值应该在运行时计算出来。(badcode吗,呵呵)。

4.关于判断是否拷贝到ram

如果是debug下,uboot直接运行在ram中,从而得到的_start值和TEXT_BASE是相等的,不需要拷贝。如果从flash启动,_start为0x0,TEXT_BASE是sdram的地址,二者是不相等的,需要拷贝。(TQ2440的SDRAM为64M,bank6,地址空间为0x30000000-0x34000000,TEXT_BASE设置为0x33D000000,即0x33D00000-0x34000000为uboot使用的空间+bss和其他的空间)。

见映射图

5.汇编中调用c函数

***********************************

MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

指令的语法格式:

MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

MCR2 p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

其中,<cond>为指令执行的条件码。当<cond>忽略时指令为无条件执行。MCR2中,<cond>为Ob1111,指令为无条件执行指令。

 <opcode_1>为协处理器将执行的操作的操作码。对于CP15协处理器来说, <opcode_1>永远为0b000,当<opcode_1>不为0b000时,该指令操作结果不可预知。

 <Rd>作为元寄存器的ARM寄存器,其值被传送到得协处理器寄存器中。

 <Rd>不能为PC,当其为PC时,指令操作结果不可预知。

 <CRn>作为目标寄存器的协处理器寄存器,其编号可能为C0,C1....C15。 <CRm>附加的目标寄存器或者原操作数寄存器,用于区分同一个编号的不同物理寄存器。当指令中不需要提供附加信息时,将C0指定为<CRm>,否则指令操作结果不可预知。  <opcode_2>提供附加信息,用于区别同一个编号的不同物理寄存器。当指令中指定附加信息时,省略<opcode_2>或者将其指定为0,否则指令操作结果不可预知。

MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

指令的语法格式:

MRC{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

MRC2 p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}