2440init.s中的大小端(问题尚未解决,解决中...)

来源:互联网 发布:java的jvm 编辑:程序博客网 时间:2024/05/22 02:02

问题尚未解决,解决中。。。


ARM处理器同时支持大端和小端两种模式


在2440init.s文件中有一段代码:
[   ENDIAN_CHANGE
    ASSERT  :DEF:ENTRY_BUS_WIDTH
    [ ENTRY_BUS_WIDTH=32
     bChangeBigEndian    ;DCD 0xea000007
    ]

    [ ENTRY_BUS_WIDTH=16
andeqr14,r7,r0,lsl #20   ;DCD 0x0007ea00
    ]

    [ ENTRY_BUS_WIDTH=8
streqr0,[r0,-r10,ror #1];DCD 0x070000ea
    ]
|
    bResetHandler
]

指令:b ChangeBigEndian
ADS 1.2小端模式下编译: 0xEA 00 00 07
ADS 1.2大端模式下编译: 0x07 00 00 EA
ARM处理器默认是小端,因此上电后,读取到的指令是默认成小端的,即读取到的指令是07 00 00 EA,指令中的字节顺序恰恰相反,如何正确执行?

摘录自网络的资料:
如果一个基于 ARM 芯片将存储器系统配置为其中一种存储器格式(如小端) ,而实际连接的存储器系统配置为相反的格式(如大端) ,那么只有以字为单位的指令取指、数据装载和数据保存能够可靠实现。其它的存储器访问将出现不可预期的结果。也就就是说在32位模式下,大小端模式对指令取指、数据装载和数据保存没有影响。(注意:如果实际的存储器格式与芯片的存储器格式不符时,只有以字为单位的数据存取才正确,否则将出现不可预期的结果。)

ARM处理器默认是小端,因此上电后,如果不通过指令修改的话,一直是小端模式,但是,如果使用ADS 1.2在编译时设置为大端模式,编译出的整个文件都将是大端模式的,同时也需要将 ENDIAN_CHANGE的值设置为{TRUE},因此在系统上电后,首先执行的就是这段代码,改变端模式,而不是先执行b ResetHandler指令系统上电后,ARM按照小端模式处理数据,认为低地址的数据时低位的,高地址的数据是高位的,因此,b ChangeBigEndian指令的机器指令0xea000007,存储时则低地址存储07,高地址ea,但是文件是大端模式,要能够完成这样的作用,编译出来的指令应该是070000ea,在存储时才会是ea000007,跟上面是不符合的但是,似乎32位模式下,ARM是小端时,读取到大端模式的指令也是能够正确处理的,为什么?

为什么?是芯片有什么内置的措施?

16位总线模式下,如何取指令呢,先取高地址还是先取低地址?取完了如何组合?
指令:andeqr14,r7,r0,lsl #20
大端模式下编译结果:0x 00 EA 07 00
小端模式下编译结果:0x 00 07 EA 00

存储器中的内容,在取指时从0x 00 EA 07 00 得到:0x EA 00 00 07
如何如何转换?

莫非在使用大端模式时,连接的数据线的顺序也要做反转处理?

复位后,ARM是小端模式
要取得指令:0x EA 00 00 07
指令是分两次读取的,第一次读取低地址00 07,第二次读取高地址的EA 00
存储器中的数据应该是:EA 00 00 07

ea000007
先取低地址数据,在寄存器中占据低位
A A+1 :  07 00
A+2 A+3:00 ea
要编译出这样的数据,大端编译时应该是:07 00 00 ea?正确吗?

如果是2个字节的大小端呢?要得到ea000007
则低位:0700
则高位:00ea
则00ea0700?正确吗?

还是00ea 0700?如何确定?
如何确定?16位模式下的大小端?

16位总线模式下,32位的数据由两个16位的数据组成:A,A+2
在大端模式下:A+1,A,A+3,A+2
16位总线模式下,取指令,先取A+3,A+2,这个位于低地址,然后再取A+1,A,因此要取得指令:EA 00 00 07
存储器中的内容应该是:00 07 EA 00


存储器中:
00 EA 07 00
16位总线模式下低地址读取:07 00
16位总线模式下高地址读取:00 EA
大端模式下,将字节序反转:
EA 00 00 07

这样小端模式读取出来就是EA 00 00 07,能够正确的执行


8位总线模式下,如何取指令?先取高地址还是先取低地址?取完了如何组合?


原创粉丝点击