ARMv6汇编中= label(等号)和[label](括号)之间有什么区别? [英] What is the difference between =label (equals sign) and [label] (brackets) in ARMv6 assembly?
问题描述
我正在跟烘焙Pi 剑桥大学的课程,其中针对Raspberry Pi的ARMv6指令集构建了一个简单的操作系统.
I'm following along with the Baking Pi course from Cambridge University, in which a simple operating system is built in the ARMv6 instruction set, targeting the Raspberry Pi.
到目前为止,我们一直在使用两种通过ldr
指令将数据加载到寄存器中的方式,现在我意识到我正在一起使用它们,但我还不完全了解它们的作用.
We've been using two ways of loading data into registers via the ldr
instruction so far and I realize now that I'm using them together, I don't fully understand what they both do.
因此,我使用了ldr r0,=0x20200000
之类的东西,我实际上将其理解为将存储在内存位置0x20200000中的数据读入寄存器r0.
So I've used things like ldr r0,=0x20200000
, which I actually understood as "read the data stored at the memory location 0x20200000 into register r0.
然后我使用了类似的东西:
Then I've used things like:
ldr r0,[r1,#4]
据我所知,这是将存储在r1指向的内存地址上的数据以4个字节的偏移量读入寄存器r0".
Which I've understood as being "read the data stored at the memory address pointed to by r1, at an offset of 4 bytes, into register r0".
然后我遇到了这个
ldr r0,=pattern
ldr r0,[r0]
pattern
在这里是.data
部分中的.int
(位图表示LED的开/关状态序列).读完此书后,我意识到我以前对=foo
的理解一定是错误的,否则以上两个说明都将做同样的事情.
pattern
here is a .int
in the .data
section (a bitmap representing a sequence of on/off states for an LED). I realize upon reading this, that my previous understanding of =foo
must be wrong, otherwise both of the above instructions would do the same thing.
=x
语法基本上更像C中的指针,而[x]
语法好像实际上是读取了x
所指向的内存吗?
Is the =x
syntax basically more like a pointer in C, while the [x]
syntax is as if the memory that is being pointed to by x
is actually read?
假设下面的C语言中的ptr
是int*
,那么我对等效组装(从概念上讲,从字面上看)的思考是否有意义?
Let's say ptr
in the C below is an int*
, do my comments thinking about equivalent assembly (conceptually, not literally) make any sense?
r0 = ptr; /* equivalent to: ldr r0,=ptr */
r0 = *ptr; /* equivalent to: ldr r0,[ptr] */
r0 = *(ptr+4) /* equivalent to: ldr r0,[ptr,#4] */
推荐答案
ldr r0,=something
...
something:
表示将标签的地址加载到寄存器r0中.然后,汇编程序在ldr指令可及的位置添加一个单词,并将其替换为
means load the address of the label something into the register r0. The assembler then adds a word somewhere in reach of the ldr instruction and replaces it with a
ldr r0,[pc,#offset]
说明
所以这个快捷方式
ldr r0,=0x12345678
表示将0x12345678加载到r0中.
means load 0x12345678 into r0.
由于是固定长度的指令,您不能在一条指令中将完整的32位立即数加载到寄存器中,它可能需要许多指令才能完全加载32位数字的寄存器.在很大程度上取决于数量.例如
being mostly fixed length instructions, you cant load a full 32 bit immediate into a register in one instruction, it can take a number of instructions to completely load a register with a 32 bit number. Depends heavily on the number. For example
ldr r0,=0x00010000
如果是ARM指令,则将用单个指令mov r0,#0x00010000替换为gnu汇编程序;对于拇指指令,尽管它仍必须是ldr r0,[pc,#offset]
will get replaced by the gnu assembler with a single instruction mov r0,#0x00010000 if it is an ARM instruction, for a thumb instruction though it may still have to be ldr r0,[pc,#offset]
这些ldr rd,=事物是快捷方式,伪指令,不是真实的.
These ldr rd,=things are a shortcut, pseudo instructions, not real.
ldr rd,[rm,#offset]
ldr rd,[rm,rn]
是真实的指令,是指从存储器的地址rm + offset或rm + rn读取,并将读取的值放入寄存器rd
are real instructions and mean read from memory at address rm+offset or rm+rn and take the value read and put it in the register rd
= something更类似于C中的& something
the =something is more like &something in C.
unsigned int something;
unsigned int r0;
unsigned int r1;
r0 = &something;
r1 = *(unsigned int *)r0;
并在组装中
something:
.word 0
ldr r0,=something
ldr r1,[r0]
这篇关于ARMv6汇编中= label(等号)和[label](括号)之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!