我想知道在组装中(在我的情况下为Y86),是否可以在数组内部具有数组?如果是的话,我将如何访问该数组内部的元素。我知道您要取消引用数组以获取其元素,但这仅是堆栈中的一个数组。有没有一种方法可以将元素放入数组内部的数组中。
示例,因为难以解释:
元素的常规抓取:
array1:
.long 0x0
.long 0x0
.long 0x0
.long 0x0
Main:
pushl %ebp
rrmovl %esp,%ebp
irmovl array1,%edx #store array1 on the stack
pushl %edx
mrmovl (%edx), %eax #get the first element of array1
rrmovl %ebp, %esp
popl %ebp
ret
现在说我有这个:
array1:
.long 0x0
.long 0x0
.long 0x0
.long 0x0
array2:
.long array1
我可以先访问array2元素,然后再访问array1的元素吗?
答案 0 :(得分:3)
pushl %edx
不会将数组存储到堆栈,而是存储第一个元素的内存地址。
在另一个示例中,array2
的第一个元素是32位整数值,它等于array1
的内存地址,因此在C语言中,array2
是指针数组
当您将array2
的第一个元素提取到某个寄存器中时,其中就有“指针”(内存地址),并且通过从该地址获取值,您将获取array1
的第一个元素(或您可以通过一些偏移量对其进行修改,以获取更多元素。
这种“数组指针数组”模式通常在以下情况下使用:相同/相似类型的多个数组,其长度不同,并且想要将它们连续存储在内存中,例如:
array0:
.long 1, 2, 3
array1:
.long 4
array2:
.long 5, 6, 7, 8
array3:
.long 9, 10
; notice the values in memory form a continuous block of 10 long values,
; so you can also access them through "array0" as single array of 10 values
mainArray:
.long array0, array1, array2, array3
现在,如果您想要值“ [2,3]”(即值“ 8”),则不能像在matrix16x16示例中那样简单地将行值2与“列大小”相乘,因为行不固定长度,因此您将首先将偏移量计算为mainArray
,例如((我将使用x86 AT&T语法,因为我不了解Y86,但您应该能够理解它,因为它们基本上是相同的指令,仅Y86的指令集就比较有限,并且您的指令名和前缀/后缀部分也更加冗长和含糊不清):
; edi = 2 (row), esi = 3 (column)
movl mainArray(, %edi, 4), %ebx ; ebx = mainArray[2] (*4 because pointers are 32 bit)
; (in x86 AT&T syntax the target memory address is "edi*4 + mainArray")
; here ebx = array2 (and "array2" is symbolic name for memory address value)
; it is NOT whole array in single register, just the memory address of first element
movl (%ebx, %esi, 4), %eax ; eax = 8 (array2[3]) (again *4 because longs are used)
; (the target memory address is "ebx + esi*4")
很抱歉没有使用y86,但是正如我所说,我不知道...如果您很难理解x86示例,请尝试描述您的注释困难,最终我可能会尝试修复语法到y86,否则可能会有其他人建议修复...
我可以先访问array2元素,然后再访问array1的元素吗?
是的,当然,这些值只是普通的32位整数(在您的y86平台上也是内存地址),因此您当然可以从顶部数组获取该子数组的地址,然后从该数组获取值子数组地址以达到“值”。尝试检入调试器,定义数组后内存如何,这些值如何表示原始源代码。
程序集是如此简单和琐碎,以至于很难在其中编写复杂的抽象,但是只要我们谈论的是单指令或内存访问,就期望它非常简单。如果您看到那里有些复杂性,则可能是误解了幕后发生的事情,它们全都是0/1位值,然后将它们移动一点(通常对于其他组来说通常为8、16、32或64)通常,您需要几条指令才能获得理想的结果,而以上这些本身就被字节/短/长/ ...支持。复杂性来自仅使用简单的复制/加/减指令的“如何编写”算法。