【问题标题】:array and assembly阵列和组装
【发布时间】:2012-03-31 02:14:28
【问题描述】:

如果我声明这 3 个数组

int a[10][10];
int b[10][15];
int c[10][30];

对于这三个数组中的哪一个,汇编代码会返回 [i][j] 元素吗?假设数组的起始地址存放在%ebx中。

pushl   %ebp
movl    %esp, %ebp
movl    8(%ebp), %edx          /* index i */
movl    12(%ebp), %ecx         /* index j */
movl    %edx, %eax
sall    $4, %eax
subl    %edx, %eax
addl    %ecx, %eax
movl    (%ebx,%eax,4), %eax
popl    %ebp
ret

你如何解决这类问题

【问题讨论】:

  • 没有我正在为我的装配期中学习

标签: c arrays assembly


【解决方案1】:

我会通过使用笔记做一些手写数学来解决这个问题,例如:

movl    8(%ebp), %edx          /* index i */
-> edx = i
movl    12(%ebp), %ecx         /* index j */
-> ecx = j
movl    %edx, %eax
-> eax = i
sall    $4, %eax
-> eax = 16 * i
subl    %edx, %eax
-> eax -= i, thus:
-> eax = 16 * i - i = 15 * i
addl    %ecx, %eax
-> eax += j, thus: 
-> eax = 15 * i + j 
movl    (%ebx,%eax,4), %eax
-> eax = array[4 * eax], thus:
-> eax = array[sizeof(int) * (15 * i + j)]

因此,在最后的eax 中,您会在位置15 * i + j 处获得给定数组(由ebx 开头指向)中的内容。这样可以正确解决:

  • 一个 int 数组
  • 第一个(最右边)维度为 15 的数组

鉴于此和您的三个数组:

int a[10][10];
int b[10][15];
int c[10][30];

这个地址是b,但不是a,也不是c

【讨论】:

    【解决方案2】:

    从取消引用数组的那一行向后工作:

    movl    (%ebx,%eax,4), %eax
    

    这里,4*eax 用作偏移量(其中 4 是sizeof(int)),所以eax 中的值是从数组开头算起的ints 的数量。现在根据从堆栈中读取的参数为eax 写一个等式...

    【讨论】:

      猜你喜欢
      • 2015-01-20
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-20
      相关资源
      最近更新 更多