ARM中的Endianness转换

ARM中的Endianness转换,arm,endianness,Arm,Endianness,如何在ARM中将大端数转换为小端数?想想如何在C这样的高级语言中转换端数,然后当您了解可以轻松地将其转换为ARM汇编时,例如 uint16_t x = 0x0102; uint16_t y = (x << 8) | (x >> 8); // y = 0x0201 uint16\u t x=0x0102; uint16_t y=(x>8);//y=0x0201 所以对于16位的情况,有两个移位(一个左移位,一个右移位)和一个OR。您应该能够在3条指令中完成此操作。您是在

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

想想如何在C这样的高级语言中转换端数,然后当您了解可以轻松地将其转换为ARM汇编时,例如

uint16_t x = 0x0102;
uint16_t y = (x << 8) | (x >> 8); // y = 0x0201
uint16\u t x=0x0102;
uint16_t y=(x>8);//y=0x0201

所以对于16位的情况,有两个移位(一个左移位,一个右移位)和一个OR。您应该能够在3条指令中完成此操作。

您是在谈论ARM的endian模式,还是在阅读其他big endian处理器编写的内容,等等

通常,在转换为/从大/小尾端时,交换字节。因此,当作为16位数字查看时,0xABCD是0xCDAB;当作为32位数字查看时,0x12345678是0x78563412

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

因此,如果您使用armv4,例如在big-endian模式和本机(little)endian模式下,对于在同一地址读取的big-endian字,值0x12345678的字读取(ldr)将是0x12345678。单词不变的意思是单词阅读给出相同的答案。在同一地址的小端模式下,地址0的字节读取为0x78,大端字节读取(ldrb)为0x12

因此,你必须超越仅仅说它是大的还是小的尾端,而是使用什么指令

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

setend be ldr r0,[r1] add r0,r0,#7 str r0,[r1] setend le 设置为 ldr r0,[r1] 加上r0,r0,#7 strr0[r1] 塞特恩德勒 一些网页会提到这种四指令字节交换,以防您想要运行本机little endian(一个非常好的主意)并使用汇编程序执行交换(这并不总是一个好主意,取决于您正在做什么)

提高采收率r3、r1、r1、ror#16 bic r3,r3,#0x00FF0000 mov r0,r1,ror#8 提高采收率r0、r0、r3、lsr#8 r1为输入,r0为输出

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

rev r0,r1 版次r0,r1
查看是否有字节反转命令,即(uu REV(),uu REV16(),uu REVSH())。这些是使用硬件的内联汇编指令,不同于上述较慢但可移植的解决方案。(,)

rev r0,r1