ARM - 确定计算机是Big-Endian还是Little-Endian

时间:2017-01-29 01:16:37

标签: assembly arm endianness

我是装配新手,特别是ARM。我试图弄清楚如何阅读以下程序如何确定计算机是Little-Endian还是Big-Endian:

MOV R0, #100
LDR R1, =0X0ABCD876       ;R1 = 0X0ABCD876
STR R1, [R0]
LDRB R2, [R0, #1]

非常感谢你!

1 个答案:

答案 0 :(得分:1)

MOV R0, #100
LDR R1, =0X0ABCD876       ;R1 = 0X0ABCD876
STR R1, [R0]
LDRB R2, [R0, #1]

汇编中没有指针。但是如果你知道足够的C来知道指针是什么,它只是一个地址,你正在访问或在偏移量处访问。这里的存储和加载使用R0作为这些操作的基地址。所以你基本上用r0中的地址指向某个内存位置,就像在C中一样,你指向某个内存位置,其中一个地址包含在一个变量中,并带有使其成为指针的语法。

它将值100硬编码为r0,这看起来像你复制了这个错误,但100是0x64,低两位是零,所以你不会得到对齐错误,我假设代码真的是mov r0,#0x100但无论如何。

下一行是迄今为止臂组装商支持的语法技巧。它通常用于标签。

ldr r3,=hello
nop
nop
nop
b .
hello: .word 0x12341234

给予

00000000 <hello-0x14>:
   0:   e59f3010    ldr r3, [pc, #16]   ; 18 <hello+0x4>
   4:   e1a00000    nop         ; (mov r0, r0)
   8:   e1a00000    nop         ; (mov r0, r0)
   c:   e1a00000    nop         ; (mov r0, r0)
  10:   eafffffe    b   10 <hello-0x4>
00000014 <hello>:
  14:   12341234    eorsne  r1, r4, #52, 4  ; 0x40000003
  18:   00000014    andeq   r0, r0, r4, lsl r0

请把标签hello的地址放到r3中,谢谢。否则我必须这样做:

ldr r3,hello_add
nop
nop
nop
b .
hello: .word 0x12341234
hello_add: .word hello

00000000 <hello-0x14>:
   0:   e59f3010    ldr r3, [pc, #16]   ; 18 <hello_add>
   4:   e1a00000    nop         ; (mov r0, r0)
   8:   e1a00000    nop         ; (mov r0, r0)
   c:   e1a00000    nop         ; (mov r0, r0)
  10:   eafffffe    b   10 <hello-0x4>

00000014 <hello>:
  14:   12341234    eorsne  r1, r4, #52, 4  ; 0x40000003

00000018 <hello_add>:
  18:   00000014    andeq   r0, r0, r4, lsl r0

这是更多的输入以获得相同的结果。

因此,如果ldr r7,=某事意味着某些东西是一个地址,并且该语法意味着将地址加载到寄存器中,那么如果某个数字是一个数字,那么汇编程序将只为我输入该数字。我也可以懒惰,少打字。

ldr r3,0x11223344
nop
nop
nop
b .

00000000 <.text>:
   0:   e59f300c    ldr r3, [pc, #12]   ; 14 <.text+0x14>
   4:   e1a00000    nop         ; (mov r0, r0)
   8:   e1a00000    nop         ; (mov r0, r0)
   c:   e1a00000    nop         ; (mov r0, r0)
  10:   eafffffe    b   10 <.text+0x10>
  14:   11223344            ; <UNDEFINED> instruction: 0x11223344

最终结果是我们将该常数输入寄存器。 arm和mips以及其他固定(ish)长度指令集对immediates有限制,所以一个不适合arm指令的立即导致它添加一些数据并像上面那样执行这个pc相对负载,但如果它适合那么

ldr r3,=0x100
nop
nop
nop
b .


00000000 <.text>:
   0:   e3a03c01    mov r3, #256    ; 0x100
   4:   e1a00000    nop         ; (mov r0, r0)
   8:   e1a00000    nop         ; (mov r0, r0)
   c:   e1a00000    nop         ; (mov r0, r0)
  10:   eafffffe    b   10 <.text+0x10>

现在我们希望汇编程序被告知你要用什么字节序,实际上如果你没有那么你有麻烦它可能不起作用。所以尽管be-8或be-32让我们假设评论是正确的。

然后STR是32位商店,请阅读您的手册。进入r0中包含的地址。所以如果这是le或be-32那么当写入地址100得到字节0x76时,地址101得到字节0xd8,地址102得到字节0xBC,地址103得到0x0A。如果是-8则地址100变为0x0A,地址101变为0xBC,地址102变为0xD8,地址103变为0x76。

ldrb说在地址r0 + 1得到一个字节,它是101,并把它放在r2中,很确定它没有签名扩展它。因此,如果le然后r2将具有0xD8,如果是-32则r2将获得0xBC并且如果是-8则r2将包含0xBC。正如杰斯特所说,然后你比较看BE和LE。

BE-32表示字不变,字操作(LDR / STR / LDM / STM)不交换,非字(LDRB,LDRH,STRB,STRH)交换。 BE-8表示字节操作不交换(字节不变),而非字节​​操作(字)交换。因此,在这种情况下,通过混合字操作和字节操作,其中一个交换和一个不依赖于大端的味道,但对于小端不交换。

当然如果汇编程序没有正确加载r1(这是整个工作的关键)那么这是一个单词操作,可能会或可能不会再次交换。

会更安全
mov r1,#0x0A000000
orr r1,r1,#0x00BC0000
orr r1,r1,#0x0000d800
orr r1,r1,#0x00000076

然后不用担心pc相对负载交换和/或汇编器放置交换的值,因此它取决于体系结构在途中取消交换。所以你必须设置正确的架构以及要求大端。