Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 数组中使用的汇编代码_Assembly_Systems Programming - Fatal编程技术网

Assembly 数组中使用的汇编代码

Assembly 数组中使用的汇编代码,assembly,systems-programming,Assembly,Systems Programming,Gcc生成以下汇编代码: int A[R][S][T]; int A[R][S][T]; int store_ele(int i, int j, int k, int *dest) { *dest = A[i][j][k]; return sizeof(A); } 问题: 我不理解上面汇编代码中的第9行和这些问题 通过一行一行地查看代码,最容易解释发生了什么 1. movl 8(%ebp), %ecx 2. movl 12(%ebp), %eax 3. leal (%e

Gcc生成以下汇编代码:

int A[R][S][T];

int A[R][S][T];
int store_ele(int i, int j, int k, int *dest) {
    *dest = A[i][j][k];
    return sizeof(A);
}
问题:


我不理解上面汇编代码中的第9行和这些问题

通过一行一行地查看代码,最容易解释发生了什么

1.  movl 8(%ebp), %ecx
2.  movl 12(%ebp), %eax
3.  leal (%eax, %eax, 8), %eax
4.  movl %ecx, %edx
5.  sall $6, %edx
6.  sub1 %ecx, %edx
7.  addl %edx, %eax
8.  addl 16(%ebp), %eax
9.  movl A(,%eax,4), %edx
10. movl 20(%ebp), %eax
11. movl %edx, (%eax)
12. movl $2772, %eax
这将使用ebp+8处的参数加载ecx,即
i

1.  movl 8(%ebp), %ecx
4.  movl %ecx, %edx
这将使用ebp+12处的参数加载eax,该参数为
j

2.  movl 12(%ebp), %eax
这将eax设置为eax+eax*8,基本上将自身乘以9。所以eax现在是
j*9

3.  leal (%eax, %eax, 8), %eax
7.  addl %edx, %eax
这将edx设置为ecx,即
i

1.  movl 8(%ebp), %ecx
4.  movl %ecx, %edx
这将它左移6位,乘以64,所以edx现在是
i*64

5.  sall $6, %edx
但是现在我们从这个值中减去ecx(它是
i
),所以edx变成
i*63

6.  sub1 %ecx, %edx
这将edx(
i*63
)添加到eax(
j*9
),因此eax现在是
i*63+j*9

3.  leal (%eax, %eax, 8), %eax
7.  addl %edx, %eax
这在ebp+16处添加了参数,即
k
,因此eax现在是
i*63+j*9+k

8.  addl 16(%ebp), %eax
这是使用偏移量eax*4访问
A
阵列并将其存储在edx中

由于eax是
i*63+j*9+k
,因此可以将其视为访问偏移量
i*63+j*9+k
处的一维int数组。我们乘以4,因为这是整数的大小

注意,您可以将该索引表达式重写为
i*7*9+j*9+k
。在此基础上,我希望您可以开始了解如何访问阵列的各个维度

9.  movl A(,%eax,4), %edx
此加载eax的参数为ebp+20,即
dest

10. movl 20(%ebp), %eax
这将edx存储在eax(
dest
)中的地址,我们刚刚从阵列中获得的数据。如果
A
是一个一维int数组,那么它有效地执行了
*dest=A[i*7*9+j*9+k]

11. movl %edx, (%eax)
这只是返回值2772,即
A
的大小

既然您现在知道了
A
的大小,如果您回顾一下
i
j
k
在取消对数组的引用时是如何相乘的,我希望您能够相当容易地计算出
R
S
T
的值

更新:计算尺寸

如果数组的维数为
R
S
T
,那么要访问
i
j
k
处的元素,您将使用什么公式

将数组视为一个大的三维块,其尺寸
R x S x T
i
索引从该块中选择一个二维切片,其尺寸为
S x T
j
索引从长度
T
的切片中选择一行。而
k
索引只是该行中的第
k

因此,一维地址可以表示为
i*S*T+j*T+k
。现在,如果您回顾一下上面反汇编中的数组计算,您没有注意到相同的模式吗?您能看到反汇编中哪些值映射到
S
T


至于查找
R
:您知道数组中的项数是693(2772字节大小除以整数大小4);您还知道,可以使用
R*S*T
计算项目数(再次考虑三维块)。因此
R*S*T=693
你知道
S
T
,所以找到
R
只是一个划分问题。

哎呀,我犯了个错误。。刚刚编辑:)这不是定义,只是int A[R][s][T]谢谢!这是一个非常友好的回答,对我来说很容易理解。。但我还是不明白一个问题。。。将方程3.1从二维扩展到三维,以提供数组元素a[i][j][k]的位置公式。如果不知道方程3.1是什么,很难回答这个问题。我得到的a的大小是693(因为整数是4),即使我不知道起始地址,我如何得到i,j,k(R,T,s)呢?我已经对我的答案进行了解释。我希望这已经足够清楚了,你可以解决剩下的问题。