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但无论如何。
下一行是 arm 汇编器目前支持的语法技巧。通常用于标签。
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,=something 意味着某事是一个地址,而该语法意味着将该地址加载到寄存器中,那么如果某事是一个数字,那么汇编器就会为我输入该数字。我也可以偷懒少打字。
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)长度的指令集对立即数有限制,因此不适合 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,如果 be-32 则 r2 将获得 0xBC,如果 be-8 则 r2 将包含 0xBC。正如 Jester 所说,您可以比较一下 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 相对负载交换和/或汇编器放置交换的值,因此它会根据架构在途中取消交换。所以你必须正确设置架构并要求大端。