ARM中的字节顺序转换 [英] Endianness conversion in ARM

查看:13
本文介绍了ARM中的字节顺序转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 ARM 中将大端转换为小端?

解决方案

你是在说 ARM 的字节序模式,还是在读一些其他大字节序处理器写的东西等等?

通常在大端/小端之间进行转换,您会交换字节.所以 0xABCD 被视为 16 位数字时为 0xCDAB 0x12345678 被视为 32 位数字时为 0x78563412.

ARM 内核 armv5 和更早版本(ARM7、ARM9 等)具有称为 BE-32 的字节序模式,这意味着大字节序字不变量.armv6 和更新版本(mpcore、cortex-somethings)具有 BE-8 或大端字节不变量.

因此,例如,如果您在大端模式和本机(小)端模式下使用 armv4,对于在同一地址读取的大端字,值 0x12345678 的字读取 (ldr) 将为 0x12345678.单词不变含义单词读取给出了相同的答案.在相同地址的小端模式下,地址 0 的字节读取将为 0x78,而大端字节读取 (ldrb) 将为 0x12.

因此,您不仅要说是大端还是小端,而是要使用什么指令.

对于 armv6 或更高版本,如果某个地址的 ldr 导致 0x12345678,那么在大端模式下,来自同一地址的 ldr 将导致 0x78563412.请注意,在大端或小端模式下,在 armv6 或更高版本上对该地址的指令获取将获取 0x12345678.ldrb 小端模式 armv6 相同数据相同地址会导致 0x78,ldrb 大端模式 armv6 或更高版本也会导致 0x78.这是因为 armv6 和更新版本是字节不变的,这意味着对相同地址的字节访问会产生相同的值,当处于大端模式时,半字、字和双字访问在这些架构上会交换.因为取指没有交换,并且因为在运行小端编译程序时字节序位在 psr 中,所以您可以切换到大端,执行一些指令然后返回本机模式,它不会影响取指或中断发生.

<上一页>定下来ldr r0,[r1]添加 r0,r0,#7字符串 r0,[r1]结束乐

一些网页会提到这个四指令字节交换,以防你想运行原生小端(一个非常好的主意)并使用汇编程序执行交换(并不总是一个好主意,取决于你在做什么).

<上一页>eor r3,r1,r1, ror #16比克 r3,r3,#0x00FF0000mov r0,r1,ror #8eor r0,r0,r3, lsr #8

r1 是它出现的输入,r0 是输出

对于 armv6 或更新的版本,可以使用

<上一页>转 r0,r1

How do I convert big endian to little endian in ARM?

解决方案

Are you talking about ARM's endian modes, or reading something written by some other big endian processor, etc?

Normally converting to/from big/little endian you swap the bytes around. So 0xABCD is 0xCDAB when viewed as a 16 bit number 0x12345678 is 0x78563412 when viewed as a 32 bit number.

ARM cores armv5 and older (ARM7, ARM9, etc) have an endian mode known as BE-32, meaning big endian word invariant. armv6 and newer (mpcore, cortex-somethings) have BE-8, or big endian byte invariant.

So if you are using an armv4 for example in big endian mode and native (little) endian mode a word read (ldr) of the value 0x12345678 would be 0x12345678 for a big endian word read at the same address. Word invariant meaning word reads give the same answer. A byte read of address zero in little endian mode of the same address would be 0x78 and big endian byte read (ldrb) would be 0x12.

So you have to go beyond just saying is it big or little endian but what instruction is being used.

For an armv6 or newer, if an ldr at some address results in 0x12345678 then in big endian mode the ldr from the same address would result in 0x78563412. Note that big or little endian mode an instruction fetch for that address on an armv6 or newer would fetch 0x12345678. An ldrb little endian mode armv6 same data same address results in 0x78, ldrb big endian armv6 or newer also results in 0x78. this is because the armv6 and newer are byte invariant meaning byte accesses to the same address result in the same value, halfword, word and double word accesses are swapped on these architectures when in big endian mode. Because instruction fetches are not swapped, and because the endian bit is in the psr while running a little endian compiled program you can switch to big endian, do a number of instructions then return to native mode and it wont affect the instruction fetches nor interrupts that occur.

setend be
ldr r0,[r1]
add r0,r0,#7
str r0,[r1]
setend le

Some web pages will mention this four instruction byte swap, in case you want to run native little endian (a very good idea) and perform the swap using assembler (not always a good idea, depends on what you are doing).

  eor r3,r1,r1, ror #16
  bic r3,r3,#0x00FF0000
  mov r0,r1,ror #8
  eor r0,r0,r3, lsr #8

with r1 being the input it appears and r0 being the output

For armv6 or newer the above can be performed with

  rev r0,r1

这篇关于ARM中的字节顺序转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆