在数组内部访问数组元素-Y86 Assembly

时间:2018-08-03 03:38:00

标签: arrays assembly x86 y86

我想知道在组装中(在我的情况下为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的元素吗?

1 个答案:

答案 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)通常,您需要几条指令才能获得理想的结果,而以上这些本身就被字节/短/长/ ...支持。复杂性来自仅使用简单的复制/加/减指令的“如何编写”算法。