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 读取与使用双数组相关的IA32汇编代码_Assembly_X86 - Fatal编程技术网

Assembly 读取与使用双数组相关的IA32汇编代码

Assembly 读取与使用双数组相关的IA32汇编代码,assembly,x86,Assembly,X86,这正是问题所在: 下面的代码转置一个M x M数组的元素,其中M 是由#define定义的常数: A.M的值是多少 B.哪些寄存器保存程序值i和 j 编写一个C代码版本的转置,利用 在此循环中发生的优化。在您的应用程序中使用参数M 代码而不是数字常量 因此,在我试图理解这一点时,我注意到它乘以4,这意味着它存储了4个字节的类型(可能是一个int或一个指针)。然后,它将i增加$52(我假设i),因为它是一个更大的值,因此将进入下一个数组),并且$52/4是13。所以我猜M=13。错了吗 对于B,我

这正是问题所在:

下面的代码转置一个M x M数组的元素,其中M 是由#define定义的常数:

A.M的值是多少

B.哪些寄存器保存程序值i和 j

编写一个C代码版本的转置,利用 在此循环中发生的优化。在您的应用程序中使用参数M 代码而不是数字常量

因此,在我试图理解这一点时,我注意到它乘以4,这意味着它存储了4个字节的类型(可能是一个int或一个指针)。然后,它将i增加$52(我假设i),因为它是一个更大的值,因此将进入下一个数组),并且$52/4是13。所以我猜M=13。错了吗

对于B,我猜%ebx包含I,%ecx包含I


对于C,我不太确定,因为我不完全理解所呈现的循环。让我试着用行号来理解,告诉我哪里错了。1.显然是循环标签的开始。2.将i的值移动到%eax中。然后是3。将[i][j]存储到t中。但是我真的不明白帮助

我修复了汇编代码中的一些错误(
%ecs
->
%ecx
(ebx)->(%ebx)
),希望我没有无意中引入新错误

在这些问题上,你几乎理解了。让我们一行一行地把代码翻译成C

   L3:
2. movl (%ebx),%eax
   // We load a 32-bit value from the address stored in ebx. We can't yet deduce the type, but let's assume int for now
   int *ebx = ??;         
   int eax = *ebx; 
3. movl (%esi,%ecx,4),%edx
   // As you noted we're dealing with 32-bit values, so when converting to C we divide the index by 4
   int *esi = ??;
   int ecx = ??; 
   int edx = esi[ecx]; 
4. movl %eax, (%esi,%ecx,4)
   esi[ecx] = eax; 
5. addl $1, %ecx 
   ecx++;
6. movl %edx, (%ebx)
   *ebx = edx; 
7. addl $52,%ebx
   // Again we have to remember to divide by the size of the type used (4)
   ebx += 13; 
8. cmpl %edi,%ecx 
9. jl .L3
   int edi = ??; 
   if (ecx < edi) goto L3;
L3:
2.移动百分比(%ebx),%eax
//我们从ebx中存储的地址加载一个32位的值。我们还不能推断类型,但现在让我们假设int
int*ebx=??;
int eax=*ebx;
3.movl(%esi,%ecx,4),%edx
//正如您所指出的,我们处理的是32位值,因此当转换为C时,我们将索引除以4
int*esi=??;
int-ecx=??;
int-edx=esi[ecx];
4.movl%eax,(%esi,%ecx,4)
esi[ecx]=eax;
5.加成$1,%ecx
ecx++;
6.移动%edx,(%ebx)
*ebx=edx;
7.加成52美元,ebx
//同样,我们必须记住除以所用类型的大小(4)
ebx+=13;
8.cmpl%edi,%ecx
9jl.L3
int edi=??;
如果(ecx
由此我们可以看出,我们有一些在内部循环外部初始化的未知值,但我们也可以很好地猜测它们是什么

  • ecx
    在每次循环迭代中递增,然后用于决定是否继续循环:显然,它是C代码中的
    j
  • edi
    是我们在决定是否循环时比较
    j
    的值,但它在内部循环中没有改变:它是
    i
  • esi
    通过
    ecx
    j
    )按行索引,因此它对应于
    &a[i][j]
  • ebx
    在每次循环迭代中增加52(13个索引位置)-正如您可能猜到的13是M-它对应于
    &M[j][i]
    ,并移动到每次迭代下一列的第
    j
    -行元素
现在我们可以回答以下问题:

A.M的值是多少

十三,

什么寄存器保存程序值i和j

edi
ecx

C.编写一个转置的C代码版本,利用此循环中发生的优化。在代码中使用参数M,而不是数字常量

在这一点上,这应该是直截了当的

1. .L3 
2. movl (%ebx),%eax 
3. movl (%esi,%ecx,4),%edx 
4. movl %eax, (%esi,%ecx,4) 
5. addl $1, %ecx 
6. movl %edx, (%ebx) 
7. addl $52,%ebx 
8. cmpl %edi,%ecx 
9. jl .L3
   L3:
2. movl (%ebx),%eax
   // We load a 32-bit value from the address stored in ebx. We can't yet deduce the type, but let's assume int for now
   int *ebx = ??;         
   int eax = *ebx; 
3. movl (%esi,%ecx,4),%edx
   // As you noted we're dealing with 32-bit values, so when converting to C we divide the index by 4
   int *esi = ??;
   int ecx = ??; 
   int edx = esi[ecx]; 
4. movl %eax, (%esi,%ecx,4)
   esi[ecx] = eax; 
5. addl $1, %ecx 
   ecx++;
6. movl %edx, (%ebx)
   *ebx = edx; 
7. addl $52,%ebx
   // Again we have to remember to divide by the size of the type used (4)
   ebx += 13; 
8. cmpl %edi,%ecx 
9. jl .L3
   int edi = ??; 
   if (ecx < edi) goto L3;