我有一个任务,对程序集进行逆向工程,以在以下代码中找到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):
store_ele:
movslq %esi, %rsi //%rsi = h
movslq %edi, %rdi //%rdi = i
movq (%rcx), %rax //moves the value from %rcx to %rax
leaq (%rdi,%rdi,4), %rdi //%rdi = 4 * i + i
leaq (%rsi,%rsi,4), %rcx //%rcx = 4 * h + h
movslq %edx, %rdx //%rdx = j
leaq (%rcx,%rdi,4), %rcx //%rcx = 4 * %rdi + %rcx = 4 * (4 * i + i) + (4 * h + h)
addq %rcx, %rdx //adds something to j
movq %rax, A(,%rdx,8) //moves some value
movl $1120, %eax //%eax = 1120
ret //returns %eax
我想问一下我对大会的理解是否正确,任何提示或帮助都很感激!
编辑:我不知道它叫什么,但是我们的教授定义了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 System V ABI (rdi中的第一个参数,请参阅该调用约定的大致摘要,或在x86标记wiki中找到更好的ABI文档(包括官方标准)的链接)。
你所说的"函数"是汇编指令。每条指令组合成一条机器指令
提示:你的注释是错误的,关于哪个参数是哪个。检查ABI中的参数传递顺序。
既然你知道声明是long int A[R][S][T]
:
A[h][i][j]
相当于*(A[h][i] + j)
,其中A[h][i]
是数组类型(大小为[T]
)。递归地应用此方法,A[h][i][j]
相当于*(base_pointer + S*T*h + T*i + j)
(其中base_pointer只是一个long*,在这种情况下,C指针数学会隐式地按sizeof(long)进行缩放)。
你似乎在正确的轨道上计算出LEAs是如何相乘的,所以你可以找到T,然后用它来找到S(通过除以h的因子)。
然后找到R,看函数返回值,它是R*S*T * sizeof(long)
。
sizeof(long)
在x86-64 System V ABI中为8字节。当然,数组中的偏移量也会按8个字节缩放,所以在获取S和T值时不要忘记将其考虑在内。