GNU ARM汇编--(十二)arm汇编指令的B真的那么简单吗?

发布者:淡雅时光最新更新时间:2015-10-14 来源: eefocus关键字:ARM汇编  汇编指令 手机看文章 扫描二维码
随时随地手机看文章
             说句题外话,在输入“指令”二字的时候,就想起了google搜索时,提示“令”不能搜索,要我换词汇.如果不能说脏话,我真就无语了.

        在前面对具体芯片的各个基本模块做完了学习后,在上一篇小结中自以为已经具备了自己写个bootloader的条件,但其实错了,我还有很多基本的知识不了解.比如编译链接gnu的linker script等等.也有很多地方只懂表面,没有做深入的理解.

        在《GNU ARM汇编--(二)汇编编译链接与运行》中,仿照网上的例子做了makefile和linker script,在那篇blog的末尾我写道“根据google,做了上面的总结,对GNU ARM汇编有了认识,并且对系统调用软中断,中断处理,uboot异常向量表等等有了探究的欲望,也对elf格式和编译链接有了兴趣,根据自己的方向和精力,后续对这些内容做一个或深或浅的学习.”

        当时看到了《linker and loader》,只是保存了,当时并没有细看,作为一个程序员,其实很多时候我们并不懂程序的细节.就像台湾有个黑客关于“hello world”的分析,当初看了他的"hello world"系列ppt,就发现原来简单的hello world里面有这么多不为人知的细节.

        这些天翻看了《linker and loader》的前面几节,也翻了《程序员的自我修养--链接装载和库》,通读了gnu.org的ld相关文档linker script.自己还对gnu的这个文档的大部分做了翻译,在自己的笔记本上写了好多页,一根笔芯也用了大半,而且让我有了久违写字写到手酸的感觉.觉得收获不少.推荐去看看,值得的.

        废话了这么多,这篇blog我倒不想写linker script或者ELF的一些细节.我想深究一下arm汇编指令中的B指令.

        很多网上的帖子都讨论过arm汇编指令的B和LDR,这里我按照我的思路来:

        首先翻一下《ARM Architecture Reference Manual》这份绝对权威的手册:

        

        

        看完上面的英文,再结合下面的实际例子做个呼应:

代码如下:

 

[html] view plaincopy
 
  1. _start: breset  
  2. ......  
  3.   
  4. reset:  
  5.         ......  


 

反汇编如下:

 

[cpp] view plaincopy
 
  1. 10000000 <_start>:  
  2. 10000000: ea00000e b 10000040   
  3. ......  
  4. 10000040 :  

[page]

 

对照汇编和反汇编的结果,一切正常.下面我们来看看ea00000e是如何表达b10000040 的?

31 28     27 26 25       24                  23 0
cond       1 0 1             L                    signed_immed_24

ea00000e转换为二进制后:

31 28     27 26 25       24                  23 0
1110      1    0   1         0                   0x00000e

cond是1110,即是条件执行的ALL,L为0表示指令是B,不是BL.signed_immed_24值为0x00000e.

signed表示有符号数.所以0x00000e就是+15,按照上图的规则:

0x10000000+14<<2+8  =  0x10000040

这里的0x10000000等地址都是VMA(虚拟内存地址),而B跳转的地址是和PC相关的,所以这部分代码是与位置无关的.

注意上面等式中的+8与流水线有关.

B和BL的跳转范围是+-32MB,24bit的有符号数,也就是-2^23--2^23,即-8MB--8MB,因为有那个<<2,所以就是+-32MB了.

 

可以再看一个例子:

代码如下:

 

[cpp] view plaincopy
 
  1. ledloop:  
  2.   
  3.   
  4. ldr r1,=0x1c0  
  5. str r1,[r2]  
  6. bl delay  
  7.   
  8.   
  9. ldr r1,=0x1a0  
  10. str r1,[r2]  
  11. bl delay  
  12.   
  13.   
  14. ldr r1,=0x160  
  15. str r1,[r2]  
  16. bl delay  
  17.   
  18.   
  19. ldr r1,=0x0e0  
  20. str r1,[r2]  
  21. bl delay  
  22.   
  23. b ledloop  


 

反汇编结果如下:

 

[cpp] view plaincopy
 
  1. 100002f0 :  
  2. 100002f0: e3a01d07 mov r1, #448; 0x1c0  
  3. 100002f4: e5821000 str r1, [r2]  
  4. 100002f8: ebffffad bl 100001b4   
  5. 100002fc: e3a01e1a mov r1, #416; 0x1a0  
  6. 10000300: e5821000 str r1, [r2]  
  7. 10000304: ebffffaa bl 100001b4   
  8. 10000308: e3a01e16 mov r1, #352; 0x160  
  9. 1000030c: e5821000 str r1, [r2]  
  10. 10000310: ebffffa7 bl 100001b4   
  11. 10000314: e3a010e0 mov r1, #224; 0xe0  
  12. 10000318: e5821000 str r1, [r2]  
  13. 1000031c: ebffffa4 bl 100001b4   
  14. 10000320: eafffff2 b 100002f0   


同样的:0x10000320+8+(-14)<<2 = 0x1000002f0

结合官方文档和两个实例,才能真正明白B指令的一些细节.而不是一些中文书上所说的正确的但是表面的内容.

 

 

        这么深入的分析指令B并不太麻烦,但是arm汇编有很多指令,不可能一一去分析.这里分析指令B,只是因为跳转指令在bootloader中很重要.而这里给出了一个方法,如果对LDR这种指令不清楚的话,可以用同样的方法来分析.

关键字:ARM汇编  汇编指令 引用地址:GNU ARM汇编--(十二)arm汇编指令的B真的那么简单吗?

上一篇:GNU ARM汇编--(十三)GNU ARM汇编下的linker script
下一篇:GNU ARM汇编--(十四)GNU ARM汇编下做任务调度

推荐阅读最新更新时间:2024-03-16 14:35

iOS程序破解——ARM汇编基础
一、Thumb指令与ARM指令 Thumb指令为16位,因此存储代码的密度高,节省存储空间。但是功能不全,它只是ARM指令(32位)集的补充,是ARM指令集下的一个子集。在初级阶段我们不需要了解这些知识,只要有个概念知道有这么个东西就可以。 二、ARM的寄存器初步了解   R0-R3:        用于函数参数及返回值的传递,超过4个参数,其它参数存在栈中,在ARM中栈是向下生长的,R0还可以作为返回值。   R4-R6, R8, R10-R11: 没有特殊规定,就是普通的通用寄存器   R7:          栈帧指针,指向母函数与被调用子函数在栈中的交界。   R9:          在iOS3.0被操作系统保
[单片机]
iOS程序破解——<font color='red'>ARM汇编</font>基础
入门级ARM汇编指令
无论是体系结构还是指令集,大家或多或少都应该对X86汇编有些了解,而对于嵌入式领域已被广泛采用的ARM 处理器,了解的可能并不多。如果你有兴趣从事嵌入式方面的开发,那么了解一些RISC 体系结构和ARM汇编的知识还是有必要的。这里,我们找出了这两种体系结构最明显的不同之处,并对此进行介绍,让大家对于RISC体系结构的汇编有一个基本的了解。首先,我们就来看一看基于RISC的ARM的体系结构。 基于RISC 的ARM CPU ARM是一种RISC体系结构的处理器芯片。和传统的CISC体系结构不同,RISC 有以下的几个特点: ◆ 简洁的指令集 为了保证CPU可以在高时钟频率下单周期执行指令,RISC指令集只提供很有限的操作(例如add,
[单片机]
入门级<font color='red'>ARM汇编指令</font>
ARM汇编 C语言 C++ 相互调用
1.汇编程序访问C语言全局变量 全局变量只能通过地址间接调用,为了访问C语言中全局变量,首先要通过extern伪指令引入全局变量,然后将其地址装入寄存器中。 对于unsigned char类型,使用LDRB/STRB访问; 对于unsigned short类型,使用LDRH/STRH访问; 对于unsigned int类型,使用LDR/STR访问; 对于char类型,使用LDRSB/STRSB访问; 对于short类型,使用LDRSH/STRSH访问; 例子: .text .global asmsubroutine .extern globvar asmsubroutine: LDR R1,=globvar LDR R0, AD
[单片机]
GNU ARM汇编--(十二)arm汇编指令的B真的那么简单吗?
说句题外话,在输入 指令 二字的时候,就想起了google搜索时,提示 令 不能搜索,要我换词汇.如果不能说脏话,我真就无语了. 在前面对具体芯片的各个基本模块做完了学习后,在上一篇小结中自以为已经具备了自己写个bootloader的条件,但其实错了,我还有很多基本的知识不了解.比如编译链接gnu的linker script等等.也有很多地方只懂表面,没有做深入的理解. 在《 GNU ARM汇编--(二)汇编编译链接与运行 》中,仿照网上的例子做了makefile和linker script,在那篇blog的末尾我写道 根据google,做了上面的总结,对GNU ARM汇编有了认识,并且对系统调用软中
[单片机]
GNU <font color='red'>ARM汇编</font>--(十二)<font color='red'>arm汇编指令</font>的B真的那么简单吗?
arm汇编学习(三)
一、ndk编译android上运行的c程序 新建个hello目录,底下要有jni目录,下面就是Android.mk文件 1.Android.mk文件内容如下: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= hello.c LOCAL_MODULE:= hello LOCAL_FORCE_STATIC_EXECUTABLE := true #LOCAL_STATIC_LIBRARIES := libc #LOCAL_CFLAGS += -Iinclude/dir -DSOMEFLAGS include $(BUILD_EXECUTABLE)
[单片机]
ARM汇编语言学习笔记(四)汇编语言中,如何调用C文件
一、目的 有时候会想一下,为什么我们要应用这些高级语言了?因为,方便啊。 汇编语言对于机器来说固然是效率很高的,但是我们编写起来其实并没有那么方便,因为他的思路还是更近机器,所以在汇编语言的编写当中,C语言也可以被使用进来,帮助大家更快更好的完成工作。 栈在汇编语言中的设置。 C语言在汇编中的调用。 二、堆栈设置 1、为什么要设置栈 因为,c语言函数需要。(如果你要问为什么需要,因为c语言所有的变量都要有地方放啊) 2、怎么设置栈 解决下面的三个问题,我们就可以成功设置栈啦。 调用者怎么向被调用者传参。 被调用者怎么返回值。 怎么恢复调用函数前的寄存器状态。 寄存器规则 这一篇寄存器规则很清楚的讲解了,我们怎么进入
[单片机]
<font color='red'>ARM汇编</font>语言学习笔记(四)汇编语言中,如何调用C文件
ARM汇编必知必会
ARM指令集: ADC 带进位的32位数加法 ADD 32位数相加 AND 32位数的逻辑与 B 在32M空间内的相对跳转指令 BIC 32位数的逻辑位清零 BKPT 断点指令 BL 带链接的相对跳转指令 BLX 带链接的切换跳转 BX 切换跳转 CDP\CDP2 协处理器数据处理操作 CLZ 零计数 CMN 比较两个数的相反数 CMP 32位数比较 EOR 32位逻辑异或 LDC\LDC2 从协处理器取一个或多个32位值 LDM 从内存送多个32位字到ARM寄存器 LDR 从虚拟地址取一个单个的32位值 MCR\MCR2\MCRR 从寄存器送数据到协处理器 MLA 32位乘累加 MOV 传送一个32位数到寄存器 MRC\MRC2
[单片机]
<font color='red'>ARM汇编</font>必知必会
ARM汇编程序基本知识
1.汇编程序的基本组成 ARM汇编语言程序中,程序是以程序段为单位组织代码的。段是相对独立的指令或者代码序列,拥有特定的名称。段的种类有代码段、数据段和通用段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据,通用段不包含用户代码和数据,所有通用段共用一个空间。段使用AREA伪操作来定义,并且说明相关属性,如 代码段定义 AREA Init, CODE, READONLY 数据段定义 AREA Stack1,DATA,READWRITE,NOINIT,ALIGN=3 等 一个汇编程序至少应该有一个代码段,可以有零或者多个数据段。在格式上,一个汇编程序需要至少
[单片机]
<font color='red'>ARM汇编</font>程序基本知识
热门资源推荐
热门放大器推荐
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved