old*_*mer 22
你是在谈论ARM的endian模式,还是读一些其他大端处理器等写的东西?
通常转换为/从big/little endian转换你周围的字节.因此,当被视为32位数时,0xABCD为0xCDAB,当被视为32位数时,0x12345678为0x78563412.
ARM内核armv5及更早版本(ARM7,ARM9等)的端序模式称为BE-32,意味着大端字不变.armv6和更新(mpcore,cortex-somethings)有BE-8或大端字节不变量.
因此,如果您在大端模式和本机(小)端模式下使用armv4,则对于在同一地址读取的大端字,值0x12345678的字读取(ldr)将为0x12345678.单词不变意义词读取给出相同的答案.在相同地址的小端模式中,地址0的字节读取将是0x78,而大端字节读取(ldrb)将是0x12.
所以你必须超越只是说它是大或小端,但正在使用什么指令.
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
有些网页会提到这四个指令字节交换,如果你想运行本机小端(一个非常好的主意)并使用汇编程序执行交换(并不总是一个好主意,取决于你在做什么).
eor r3,r1,r1, ror #16 bic r3,r3,#0x00FF0000 mov r0,r1,ror #8 eor r0,r0,r3, lsr #8
r1是输入,r0是输出
对于armv6或更新版本,可以执行上述操作
rev r0,r1
考虑一下如何在 C 等高级语言中转换字节序,然后当您理解后,您可以轻松地将其转换为 ARM 汇编,例如
uint16_t x = 0x0102;
uint16_t y = (x << 8) | (x >> 8); // y = 0x0201
Run Code Online (Sandbox Code Playgroud)
因此,对于 16 位情况,您有两个移位(左移和右移)和一个 OR。您应该能够通过 3 条指令来完成此操作。
| 归档时间: |
|
| 查看次数: |
25936 次 |
| 最近记录: |