组员:20135224(4)陈实,201352XX(2)刘蔚然
3.60:
题目要求:求用#difine声明的三维数组的大小
并利用反汇编工程技术推算出A[R][S][T]中,R ,S, T的大小
1.利用二维数组的等式,推算三维数组的地址等式
2.根据汇编代码,计算R S T 的值
解题思路:
1 根据二维数组提供的等式以及数组在内存分布上的特点可以知道,三维数组的基本框架
&D[i][j]=X+L(C*i+j)可以知道,当D[i][j][k]变成三维时,基本框架为&D[i][j][k]=x+L(C1*i+C2*j+k);
2 根据存储空间是按行到列的顺序可以知道,遍历时从i到K的,则对应的C1=(S+1)*(T+1),C2=T+1;
3 对应的三维数组公式为&D=x+L*(C1*i+C2*j+k) (其中,L为字节数,C1 C2已知)
4 根据已知的汇编代码推算公式:
movl 8(%ebp),%ecx #将i的值赋给ECX
movl 12(%ebp),%eax #将j的值赋给eax
leal (%eax,%eax,8) ,%eax #eax:j+8*j=9j
movl %ecx %edx #将i的值给到edx
sall $6 , %edx #edx:i<<6,相当于i*64
subl %ecx,%edx #edx:64i-i=63i
addl %edx,%eax #eax:63i+9j
addl 16(%ebp), %eax #eax:63i+9j+k
movl A(%eax,4),%edx #取出相应地址的存入的数据
movl 20(%edp),%eax #取出*dest
movl %edx ,(%eax) #*dest 赋值
movl $2772 , %eax #将数组总长度表示,即数组大小为2772
由以上的反编译可以知道对应的寻址的地方为63i+9j+k
对应于公式可以知道C2=9; C1=63;
所以T=9-1=8;
S=63/9-1=7-1=6;
由于字节数L是取的4的双字,所以2772/4=693
则R=693/T*S=693/63-1=11-1;
注意事项:
1 在进行翻译的时候,应该明确标记变量所存放的寄存器,更要明确知道进行运算的是寄存器值还是寄存器对应的存储器值
2 数组由于默认规定有0的数值,因而构成的三维数组对应的数值都要减1操作才能保证大小
3 sizeof规定的是申请空间的大小,i j K 则不是对应空间大小而是对应的一个数组下的一个数值
作业结果:
1 对应的三维数组D[R][S][T]=x+4(63i+9j+k)
2 对应的R=11,S=7, T=9
结果验证:
组员:20135224(2)陈实,20135226(4)黄坤
A 用指针索引的方式编写相同的数组索引的冒泡程序C代码
B 将所得的C程序用Y86程序表述出来
1 将题目所给的数组元素代码转换成指针索引的代码
具体方法为:将指针赋给数组的头地址,然后按位移动指代
C格式:int *data=a;
*(data+i);
2 将程序复写,并加入头文件以及主函数使其能正常调用以及相应传参
3 将所得的C程序汇编一下获得相应的汇编代码
格式:gcc -S xxx.c -o xxx
4 利用所得的汇编代码,用正则表达式去掉相应的“."与无关项之后进行Y86代码替换
涉及格式:g/\.\d; dd
5 将所得的Y86代码与用机器产生的反汇编代码比对,验证准确性
对应对比及修改:
1 对应的指针代码要在能运行与检测的基础上构建,在调用相应的冒泡程序时,因先利用GCC -G后调试一下
带来的问题:在没有可执行的程序做保证的话会由于书写错误或者指代错误等错误因素导致数据意外存储而没有报错,这样无法得到汇编及正确的代码
2 在可执行的C代码汇编版本中:movl指令对应的Y86指令有三个,要注意区分三者后带的参数类型
3 Y86没有相应的乘除法操作,要转换成加减或者与,抑或运算完成,为方便起见,规定的数据不讨论符号,对于乘除法操作,以最优解替换
本次家庭作业相对的难点在于如何利用基本的加减,与等操作完成复杂的移位乘除等复杂算法,对于更好理解机器的运算过程有较好的帮助
组员:20135224(4)陈实,20135226(2)黄坤