您的位置 首页 硬件

深入分析S3C2440发动代码中巨细端问题

一、ADS12中关于大小端的设置以及对编译后的代码的影响下面是一段代码在线段模式下编译,生成的二进制文件的内容大端模式下编译,生成二进

一、ADS1.2中关于巨细端的设置以及对编译后的代码的影响

下面是一段代码在线段形式下编译,生成的二进制文件的内容
大端形式下编译,生成二进制文件的内容
依据上面的内容可以看出:它们的字节序是相反的,也便是说,ADS1.2中对巨细端的设置会影响终究生成的二进制文件的字节序。

二、S3C2440发动代码中与巨细管相关的代码

Option.inc中相关代码
[plain]view plaincopy

print?

  1. GBLLENDIAN_CHANGE
  2. NDIAN_CHANGESETL{FALSE}
  3. GBLAENTRY_BUS_WIDTH
  4. NTRY_BUS_WIDTHSETA16

2440init.s中相关代码

[plain]view plaincopy

print?

  1. AREAInit,CODE,READONLY
  2. ENTRY
  3. EXPORT__ENTRY
  4. __ENTRY
  5. ResetEntry
  6. ;1)Thecode,whichconvertstoBig-endian,shouldbeinlittleendiancode.
  7. ;2)ThefollowinglittleendiancodewillbecompiledinBig-Endianmode.
  8. ;Thecodebyteordershouldbechangedasthememorybuswidth.
  9. ;3)Thepseudoinstruction,DCDcannotbeusedherebecausethelinkergenerateserror.
  10. ASSERT:DEF:ENDIAN_CHANGE
  11. [ENDIAN_CHANGE
  12. ASSERT:DEF:ENTRY_BUS_WIDTH
  13. [ENTRY_BUS_WIDTH=32
  14. bChangeBigEndian;DCD0xea000007
  15. ]
  16. [ENTRY_BUS_WIDTH=16
  17. andeqr14,r7,r0,lsl#20;DCD0x0007ea00
  18. ]
  19. [ENTRY_BUS_WIDTH=8
  20. streqr0,[r0,-r10,ror#1];DCD0x070000ea
  21. ]
  22. |
  23. bResetHandler
  24. ]
  25. bHandlerUndef;handlerforUndefinedmode
  26. bHandlerSWI;handlerforSWIinterrupt
  27. bHandlerPabort;handlerforPAbort
  28. bHandlerDabort;handlerforDAbort
  29. b.;reserved
  30. bHandlerIRQ;handlerforIRQinterrupt
  31. bHandlerFIQ;handlerforFIQinterrupt
  32. ;@0x20
  33. bEnterPWDN;Mustbe@0x20.
  34. ChangeBigEndian
  35. ;@0x24
  36. [ENTRY_BUS_WIDTH=32
  37. DCD0xee110f10;0xee110f10=>mrcp15,0,r0,c1,c0,0
  38. DCD0xe3800080;0xe3800080=>orrr0,r0,#0x80;//Big-endian
  39. DCD0xee010f10;0xee010f10=>mcrp15,0,r0,c1,c0,0
  40. ]
  41. [ENTRY_BUS_WIDTH=16
  42. DCD0x0f10ee11
  43. DCD0x0080e380
  44. DCD0x0f10ee01
  45. ]
  46. [ENTRY_BUS_WIDTH=8
  47. DCD0x100f11ee
  48. DCD0x800080e3
  49. DCD0x100f01ee
  50. ]
  51. DCD0xffffffff;swinv0xffffffissimilarwithNOPandrunwellinbothendianmode.
  52. DCD0xffffffff
  53. DCD0xffffffff
  54. DCD0xffffffff
  55. DCD0xffffffff
  56. bResetHandler

咱们可以看到,在Option.inc将ENDIAN_CHANGE设置FALSE,程序将直接运转b ResetHandler,S3C2440默许是处于小端形式,ADS1.2中的设置默许也是小段形式,全部惊涛骇浪。

现在,咱们在ADS1.2中设为打断形式,并把ENDIAN_CHANGE设置FALSE设为TURE,现在问题就来了,请看下面的剖析。
在编译程序时,依据ENTRY_BUS_WIDTH宏会将下面三条指令的之一放在0地址处
b ChangeBigEndian ;DCD 0xea000007
andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
其实这三条指令的功用都是相同,仅仅依据数据带宽调整了字节序,都是跳转到0x24处的ChangeBigEndian履行,ChangeBigEndian的效果便是经过协处理CP15中的寄存器C1来改动S3C2440的巨细端形式。
先来看一下这三条指令。由于咱们已经在ADS中设置为大端形式,所以这些指令是以大端形式进行编译的,而S3C2440此刻仍是小端形式,S3C2440怎么能履行大端形式下的指令呢,比方b ChangeBigEndian ;DCD 0xea000007???
原因如下:
假如一个根据 ARM 芯片将存储器系统配置为其间一种存储器格局(如小端) ,而实践衔接的存储器系统配置为相反的格局(如大端) ,那么只要以字为单位的指令取指、数据装载和数据保存可以牢靠完成。其它的存储器拜访将呈现不行预期的成果。也就便是说在32位形式下,巨细端形式对指令取指、数据装载和数据保存没有影响。(留意:假如实践的存储器格局与芯片的存储器格局不符时,只要以字为单位的数据存取才正确,不然将呈现不行预期的成果。)
b ChangeBigEndian在大端形式下机器码是0xea000007,这是32位形式下,其四个字节从低到高分别是:07 00 00 ea。那没b ChangeBigEndian这条指令在8位形式下,要被小端形式的S3C2440履行,就要人为的修正为0x070000ea。在存储器中存储的次序:从低地址到高地址分别是 07 00 00 ea,S3C2440按小端形式取指令时,获得是0xea000007。
b ChangeBigEndian这条指令在16位形式下,要被小端形式的S3C2440履行,就要人为的修正为0x0007ea00。在存储器中存储的次序:从低地址到高地址分别是 0007 ea00,S3C2440按小端形式取指令时,获得是0xea000007。
后边修正协处理CP15中的寄存器C1的代码时相似的。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/yingjian/262373.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部