我的教授在周五的演讲中向我们提出了一个“挑战性”问题。他给我们提供了一个C程序的程序集,然后从C代码中删除了两个常量。
大会:
sum_element:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
movl 12(%ebp),%ecx
sall $2,%ecx
leal 0(,%eax,8),%edx
subl %eax,%edx
leal (%eax,%eax,4),%eax
movl mat2(%ecx,%eax,4),%eax
addl mat1(%ecx,%edx,4),%eax
movl %ebp,%esp
popl %ebp
ret
然后是C代码:
#define M ____
#define N ____
int mat1[M][N];
int mat2[N][M];
int sum_element(int i, int j)
{
return mat1[i][j] + mat2[i][j];
}
然后他问我们M和N的值是多少。
到目前为止,我所做的是:
movl %esp,%ebp
(这会将esp寄存器移到ebp寄存器中)movl 8(%ebp),%eax
(这会将ebp寄存器中的8的内容移到eax寄存器中)movl 12(%ebp),%ecx
(这会将ebp寄存器中的12的内容移到ecx寄存器中)sall $2,%ecx
(这会将ecx上存储的数字左移2位,因此除以4)leal 0(,%eax,8),%edx
(我不确定表达式前面的0在做什么,否则会将eax * 8加载到edx中)subl %eax,%edx
(edx = edx-eax)leal (%eax,%eax,4),%eax
(eax = eax ^ 2 * 4)movl mat2(%ecx,%eax,4),%eax
(eax =无论mat2(ecx,eax,4)是什么)addl mat1(%ecx,%edx,4),%eax
(eax = eax +无论mat1(ecx,edx,4)是什么)我不了解的部分是mat1,mat2和前面带0的标签。
谢谢!
编辑:总结到目前为止,我有:
ecx=ecx/4
edx=eax*8-eax
eax=eax*4+eax
我以为知道了mat1和mat2是什么之后就可以计算M和N的值了,但是我要么错过了显而易见的事情,要么还有更多工作要做。任何方向都很好。
ecx是j而eax是i吗?
再次感谢!
最佳答案
mat1
和mat2
只是存储位置的命名地址,与C代码相同。
movl mat2(%ecx,%eax,4),%eax -> load *(ecx + mat2 + (eax * 4)) into eax
addl mat1(%ecx,%edx,4),%eax -> add *(ecx + mat1 + (edx * 4) to eax
其中,
mat2
和mat1
是表示某些地址的常数数值,这对于汇编程序是已知的。leal
指令只是“整数加/乘”运算的俗称,通常用于地址计算:leal 0(,%eax,8),%edx -> load eax * 8 + 0 into edx
关于c - 将程序集转换为C,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23332004/