我正在学习这门课程,而且我真的很难理解指令.align
的概念。
这是一个我无法理解的例子:
我知道数据段内部有地址,从0x10010000,0x10010020开始等。
我知道,在每个地址中,有8个内存字段,每个字段有32位。
现在,我不明白的是,地址0x10010010内的var2
如何以及为何? str1
位于地址0x10010003内,因为我们为var1
保留了3位。
最后一件事是,指令.align' doing? when I tested it in Mars4, it only shifted the data into the next memory field when I used
究竟对齐3`及以上,但我真的不明白。
我很抱歉,如果这是非常令人困惑的家伙,我在这里绝望。
答案 0 :(得分:11)
对齐对于MIPS处理器很重要,它只喜欢从内存读取多字节值,地址是数据大小的倍数。
.ASCIIZ字段可以放在任何地方,因为一次读取一个字节的字符串。所以把它放在0x10010003就好了。
.WORD字段必须与4的倍数对齐。因此不能将其放在0x1001000E(字符串后面的下一个可用位置)。汇编程序故意移动该值并留下两个未使用的字节。到下一个地址,即4的倍数,0x10010010。
.ALIGN指令是一种覆盖默认对齐规则的方法。指令后面的下一个字段将对齐到2的幂的倍数,其中n是.ALIGN值。在你的情况下,pow(2,3)= 8字节。
您所看到的是,如果没有.ALIGN指令,.HALF字段将存储在0x10010014。不是8的倍数,因此它被移动到0x10010018。
这个例子是人为的,没有明显的理由在这里使用.ALIGN指令,因为.HALF只需要一个2的倍数的对齐,所以将它存储在0x10010014就可以了。
答案 1 :(得分:2)
某些汇编指令暗示数据是以对齐方式存储的,这意味着从一个幂为2的的地址开始。回想一下MIPS中的几个约定:
(1)“word”是4个字节(有时你会看到它被定义为2个字节),
(2)半字(.half)是2个字节,
(3).asciiz null终止字符串(如在C中)。
使用它,您已经解释了如何存储var1和str1。为什么在var2之前有2个空字节的缓冲区?因为它被声明为.word,并且(通过上面的(1))将从存储位置开始存储,该存储位置是4的倍数。如果你将它声明为.half,则str1之间没有2个空字节和var2。
var2声明为.half - 它是一个16位(2字节)地址,适合一个。但是,在声明对齐之前,将对齐方式更改为3.现在,检查第一句:这是你提升2的 power ;所以我们实际上对齐到8.这意味着在被覆盖之前,变量将按声明的方式放置,但另外它们的初始存储位置必须是8的倍数。因此,汇编器插入4个空字节以将var3存储为8的倍数。