ARMv6程序集中= label(等号)和[label](括号)之间有什么区别?

d11*_*wtq 17 assembly arm

我正在跟随剑桥大学的Baking Pi课程,其中一个简单的操作系统是在ARMv6指令集中构建的,目标是Raspberry Pi.

ldr到目前为止,我们一直使用两种方法通过指令将数据加载到寄存器中,现在我意识到我正在使用它们,我不完全理解它们的作用.

所以我使用的东西ldr r0,=0x20200000,我实际上理解为"将存储在存储单元0x20200000的数据读入寄存器r0.

然后我用过以下的东西:

ldr r0,[r1,#4]
Run Code Online (Sandbox Code Playgroud)

我已经理解为"读取存储在r1指向的存储器地址的数据,以4字节的偏移量进入寄存器r0".

然后我遇到了这个:

ldr r0,=pattern
ldr r0,[r0]
Run Code Online (Sandbox Code Playgroud)

pattern这里是一个.int.data部分(表示接通/断开状态的用于LED的序列的位图).我在阅读本文时意识到,我之前的理解=foo一定是错的,否则上述两条指令都会做同样的事情.

=x语法基本都像在C的指针,而[x]语法如果被指向的内存x实际上是读?

让我们说ptr下面的C是一个int*,我的评论是否考虑等效组装(概念上,不是字面意思)有意义吗?

r0 = ptr;     /* equivalent to: ldr r0,=ptr     */
r0 = *ptr;    /* equivalent to: ldr r0,[ptr]    */
r0 = *(ptr+4) /* equivalent to: ldr r0,[ptr,#4] */
Run Code Online (Sandbox Code Playgroud)

old*_*mer 18

ldr r0,=something
...
something:
Run Code Online (Sandbox Code Playgroud)

意味着将标签的地址加载到寄存器r0中.然后,汇编器在ldr指令的某个地方添加一个单词,并用a替换它

ldr r0,[pc,#offset]
Run Code Online (Sandbox Code Playgroud)

指令

所以这个捷径

ldr r0,=0x12345678
Run Code Online (Sandbox Code Playgroud)

表示将0x12345678加载到r0中.

大多数是固定长度的指令,你不能在一条指令中将一个完整的32位立即加载到一个寄存器中,它可能需要许多指令来完全加载一个32位数的寄存器.很大程度上取决于这个数字.例如

ldr r0,=0x00010000
Run Code Online (Sandbox Code Playgroud)

将被gnu汇编程序替换为单个指令mov r0,如果它是ARM指令则为#0x00010000,对于thumb指令将取代,尽管它可能仍然必须是ldr r0,[pc,#offset]

这些ldr rd,=事物是快捷方式,伪指令,不是真实的.

ldr rd,[rm,#offset]
ldr rd,[rm,rn]
Run Code Online (Sandbox Code Playgroud)

是真实的指令,意思是从地址rm + offset或rm + rn的内存读取并读取值并将其放入寄存器rd

=某事更像是C中的东西.

unsigned int something;
unsigned int r0;
unsigned int r1;

r0 = &something;
r1 = *(unsigned int *)r0;
Run Code Online (Sandbox Code Playgroud)

并在组装

something:
    .word 0

ldr r0,=something
ldr r1,[r0]
Run Code Online (Sandbox Code Playgroud)