反编译IA32 32位AT&T汇编代码中的一个函数C
[编辑] 有人可以向我解释在这个问题中,我们如何得到M和N的值,遍历相应汇编代码的每一行?反编译IA32 32位AT&T汇编代码中的一个函数C
我总是被困在movl array2部分。我们如何推导出常数M和N的值:
M和N常量使用#
#define M <some value>
#define N <some value>
int array1[M][N];
int array2[N][M];
int copy(int i, int j)
{
array1[i][j] = array2[j][i];
}
如果上述代码生成以下汇编代码中定义?
copy:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl 8(%ebp), %ecx
movl 12(%ebp), %ebx
leal (%ecx, %ecx, 8), %edx
sall $2, %edx
movl %ebx, %eax
sall $4, %eax
subl %ebx, %eax
sall $2, %eax
movl array2(%eax, %ecx, 4), %eax
movl %eax, array1(%edx, %ebx, 4)
popl %ebx
movl %ebp,%esp
popl %ebp
ret
好吧,经过很多研究,我可以找到解决方案。纠正我,如果我错了。
通过以下步骤组装所以要通过步骤:(由行号为便于)
M和N是使用的#define
int array1[M][N];
int array2[N][M];
int copy(int i, int j)
{
array1[i][j] = array2[j][i];
}
copy:
1 pushl %ebp
2 movl %esp, %ebp
3 pushl %ebx
4 movl 8(%ebp), %ecx
5 movl 12(%ebp), %ebx
6 leal (%ecx, %ecx, 8), %edx
7 sall $2, %edx
8 movl %ebx, %eax
9 sall $4, %eax
10 subl %ebx, %eax
11 sall $2, %eax
12 movl array2(%eax, %ecx, 4), %eax
13 movl %eax, array1(%edx, %ebx, 4)
14 popl %ebx
15 movl %ebp,%esp
16 popl %ebp
ret
推
%ebp
入堆栈 定义的常量
%ebp
点%esp
推
%ebx
入堆栈%ecx
等于int i
(指数为数组访问)%ebx
等于int j
(指数为数组访问)%edx
等于8 * %ecx + %ecx
或9i
%edx
的2
%eax
左二进制移位后等于36i
等于%EBX或j
%eax
的4
%eax
左二进制移位后等于16j
等于%eax - %ebx = 16j - j = 15j
%eax
等于60j
的2
%eax
左二进制移位后等于数组2元件与索引[4%ecx + %ebx] or [4i + 60j]
元索引
[ 4%ebx + %edx ] or [ 4j + 36i ]
的ARRAY1等于%eax
或[4i + 60j]
两个数组元素的交换在12和13中使用%eax作为 中间寄存器完成。
%ebx
弹出%esp
的旧值恢复%ebp
弹出
现在我们假设array1[i][j]
的元件访问权限等于4Ni + 4j
和array2[j][i]
的元素访问等于4Mj + 4i
。
(作为int的每个索引项中的4是4个字节,而i,j是从起始数组位置的单独偏移量) 这是真的,因为C将数组以行的形式存储。
因此,我们得到,M = 15和N = 9。
你需要检查装配的其他部分。例如,如果定义了M和N为8两者,会发现在装配
array1:
.zero 256
array2:
.zero 256
以下,因为我的机器上,int是4个字节,8次8是64和64 * 4 = 256 。样品组件可以找到here。
我认为有一种方法可以找到答案,而不必假设M和N的值,但我认为我们不需要知道程序集的其他部分。 – 24dinitrophenylhydrazine
你真的希望我们输入所有的?不要发布代码图片!请解决你的问题。 – ikegami
为什么代码为图像? –
当你说“我们得到M和N的值”时,你是什么意思?你的意思是'我'和'j'? – ikegami