您好、欢迎来到现金彩票网!
当前位置:手机棋牌游戏下载 > 伪指令 >

ARM编程进阶之一-ARM汇编伪指令

发布时间:2019-06-27 00:32 来源:未知 编辑:admin

  首先我们来回答“基本寻址模式与基本指令”一文中提出的问题。“如果我们需要mov r0, #10000这样的指令,应该怎么办?(常数10000不能在机器指令32bit中的低12bit中被表示出来)”。当你进行编译的时候,“Error:All70E”的错误就会出现,如下图。

  其实,这个问题很容易解决,只需要将mov r0, #10000换为ldr r0, =10000即可。为什么这样就可以了呢?因为,这里的ldr r0, =10000并非我们已经学过的ldr指令,而是一条伪指令,编译器会将这条伪指令替换为:

  DCD所分配的内存空间中存放了整数10000,该内存空间被称为literal pool,中文名称“文字池”。由于整个程序都是由编译器编译的(包括文字池的分配),所以很显然编译器能够知道ldr指令在内存中的地址与文字池在内存中的位置之间的偏移量,因此编译器就可以正确地使用以pc为基址,采用相对寻址的ldr指令将文字池中的数取出加载到寄存器r0中。由此可见,编译器对于ldr r0, =10000这条伪指令的处理,其实质是:

  在汇编源程序时,LDR伪指令被编译器替换成一条合适的指令和存放常数的文字池。汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。

  由于,4byte可以存放任何int型整数,这样一来,常数就可以是任何int型整数,而不再受制于12bit的限制。当然此时的常数是存放在内存中的,而不是存放在机器指令的32bit编码中的。

  a)、ldr r0, [pc, #-4]中是-4,而不是+4,是由于流水线的原因(参见“流水线对PC值的影响”一文)。今后对于流水线的这种影响,我将不再予以特别说明。

  c)、从语法上来看,与ARM指令的LDR相比,伪指令LDR的参数有“=”号,没有“#”号

  d)、如果常数能够被12bit表示出来,例如:ldr r0, =0x100,那么,编译器对该伪指令的处理,是使用MOV(或者MVN)指令代替该LDR伪指令,例如:mov r0, #0x100,而不会采用ldr指令+文字池的方式。

  除了 ldr 寄存器, =常数 这种形式外,还有ldr 寄存器, =标号 这种形式也经常被使用,下面我就来讲解这种形式的ldr伪指令。

  由上图可见:ldr pc, =InitStack这条伪指令的作用是将标号InitStack所代表的地址赋予pc。 这里会使我们产生几个疑问:

  这是因为bl指令的跳转范围是正负32M,而InitStack所代表的位置有可能距离ldr pc, =InitStack超过32M,此时bl就无能为力了。竟然存在这么大范围跳转的程序(这似乎意味着编译出来的二进制可执行文件的大小会操作32M),这一点似乎令我们感到非常震惊。事实上是:大小超过32M的可执行程序的确几乎不可能出现,但即使是很小的二进制程序中也可能进行大范围(超过32M)的跳转,这一点在bootloader程序中几乎是必然的。

http://tennisinspokane.com/weizhiling/219.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有