C 通过汇编查找数组的维数

C 通过汇编查找数组的维数,c,assembly,multidimensional-array,x86,reverse-engineering,C,Assembly,Multidimensional Array,X86,Reverse Engineering,我的任务是对程序集进行逆向工程,以在以下代码中找到R、S和T的值。假设R、S和T是用#define声明的常量 long int A[R][S][T]; int store_ele(int h, int i, int j, long int *dest) { A[h][i][j] = *dest; return sizeof(A); } 编译此程序时,GCC生成以下汇编代码(带-O2): 我想问一下,我对大会的理解是否正确,是否感谢任何提示或帮助 编辑:我不知道它叫什么,但我们的教授

我的任务是对程序集进行逆向工程,以在以下代码中找到R、S和T的值。假设R、S和T是用
#define
声明的常量

long int A[R][S][T];
int store_ele(int h, int i, int j, long int *dest)
{
   A[h][i][j] = *dest;
   return sizeof(A);
}
编译此程序时,GCC生成以下汇编代码(带-O2):

我想问一下,我对大会的理解是否正确,是否感谢任何提示或帮助

编辑:我不知道它叫什么,但我们的教授定义了
movq:source,destination
和其他类似的汇编指令,其中第一个参数是source,第二个是destination

编辑2:最大的问题是如何仅基于程序集找到三个常量的值。我想

movq   %rax, A(,%rdx,8) //moves some value
movl   $1120, %eax      //%eax = 1120
ret                     //returns %eax
将在发现它的作用方面发挥主要作用,但我不知道该如何处理它

编辑3:不知道我是否应该给出答案,但是如果有人可能有同样的问题,我得到了t=5、S=4和R=7,其中R=1120/t*S*8,我从这个线程得到的帮助匹配系数中得到了t和S。

这是x86-64 AT&t语法(助记符源,dest),带有x86-64系统V ABI(rdi中的第一个参数,请参见此,或者在TagWiki中找到指向更好的ABI文档(包括官方标准)的链接)

你称之为“函数”的是汇编指令,每一个都汇编成一条机器指令


提示:关于哪个arg是哪个arg,您的注释是错误的。请检查ABI以了解arg传递顺序

因为您知道声明是长int A[R][S][T]:

A[h][i][j]
相当于
*(A[h][i]+j)
,其中
A[h][i]
是一种数组类型(大小
[T]
)。递归地应用它,
A[h][i][j]
相当于
*(基指针+S*T*h+T*i+j)
(其中base_指针只是一个long*,用于C指针数学,在本例中,它隐式地按sizeof(long)进行缩放)

你似乎在正确的轨道上计算出LEA是如何相乘的,所以你可以找到T,然后用它来找到S(除以h的因子)

然后要找到R,请查看函数返回值,即
R*S*T*sizeof(long)


sizeof(long)
在x86-64系统V ABI中是8个字节。当然,数组中的偏移量也会按8个字节进行缩放,所以在获取S和t值时不要忘记将其计算出来。

什么寄存器携带什么取决于ABI。我假设这是Linux(如果我没记错的话,System V ABI)?如果是,请为平台添加标签(例如Linux、Windows、OS X等)还有,什么是
#为
R
s
T
定义
s?@Olaf:完全不同意。当代码这么简单时,未优化的代码充满了存储/重新加载的噪音。@PeterCordes:我同意Olaf。未优化的代码可能会有更多的“噪音”但是,它可以更容易地与原始代码相关,特别是因为那些加载/存储序列和省略优化技巧。只有那些习惯于阅读大量汇编程序的人会认为优化代码更容易阅读。但不是初学者。数组(2*2*2*2*2*2*5*7),这应该会给你一些线索。@RudyVelthuis:这是公平的,所有这些LEA都不如imul那么清晰,有立即数。gcc的成本模型认为imul比现代Intel更贵,有时会使用一个以上的LEA(甚至可能超过两个LEA)。不过,一般来说,
-Og
(针对调试进行优化)是一个很好的选择,因为每个源代码行的操作基本上仍然存在于asm中。我不太理解查找t的第一部分,但是对于R,您说1120=RST*8(sizeof(long))@JMei:yes。要查找t,请查看
a(,%rdx,8)中的存储
.RDX是几件事情的总和。看看哪一部分可以追溯到
j
的倍数,这就是你的T。(此时应用8的缩放(sizeof(long),在使用RDX作为索引的寻址模式下使用缩放因子,因此在此之前你不必担心。)从我能回溯的角度来看,rdx=j+%rcx=j+(4*5i)+5h。而movq%rax,A(,%dx,8)将rax的地址移动到第二个地址?我试图编辑我的上一条注释以合并我的两条注释,但它不允许我。//因此,如果它试图匹配我回溯到您放入的模板中的内容(base_pointer+STh+Ti+j),T=5,S=4,求R,RST*8=1120,R=1120/(5*4*8)=7?这部分你在做什么“既然你知道声明很长,那么A[R][S][T]:A[h][i][j]相当于(A[h][i]+j),其中A[h][i]是一种数组类型(大小为[T])。递归地应用这一点,A[h][i][j]相当于*(基指针+STh+Ti+j)(其中base_指针只是一个long*,用于C指针数学,在这种情况下,它隐式地按sizeof(long)进行缩放)
movq   %rax, A(,%rdx,8) //moves some value
movl   $1120, %eax      //%eax = 1120
ret                     //returns %eax