2010-11-26 128 views

回答

1

想想如何以C这样的高级语言转换字节顺序,然后当你明白你可以很容易地将它转换成ARM程序集时,

uint16_t x = 0x0102; 
uint16_t y = (x << 8) | (x >> 8); // y = 0x0201 

因此,对于16位的情况,你有两个班次(一个左和一个右)和一个OR。你应该能够在3条说明中做到这一点。

17

你说的是ARM的endian模式,还是读一些其他的big endian处理器等写的东西?

通常转换为/从大/小端转换字节。所以0xABCD当被视为32位数字时,被视为16位数字0x12345678时为0x78563412。

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

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

所以你必须超越只是说它是大还是小,但是使用了什么指令。

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

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

某些网页会提到这4个指令字节交换,如果你想运行本地小端(一个非常好的主意),并使用汇编(并不总是一个好主意,取决于你进行交换是做)。

 
    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 
2

进行查看是否有一个字节反转命令即( __REV(),__REV16(),__REVSH())。这些是使用硬件的内联汇编指令,与上面回答中的较慢但便携式工作不同。 (link1link2