我有一个分配来对程序集进行反向工程,以便在以下代码中找到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.
答案 0 :(得分:6)
那个x86-64 AT& T语法(助记符源,目标),x86-64 System V ABI(rdi中的第一个arg,请参阅此approximate summary of that calling convention,或找到更好ABI的链接x86标签wiki中的docs(包括官方标准)。
你在呼唤什么"功能"是装配说明。每一个都组装成一台机器指令。
提示:你的意见是关于哪个arg是错误的。检查ABI是否有arg-passing命令。
因为您知道声明是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)缩放)。
您似乎正在研究LEA如何成倍增加,因此您可以找到T,然后使用它来找到S(通过将因子除以h)。
然后找到R,查看函数返回值,即R*S*T * sizeof(long)
。
sizeof(long)
V ABI是8个字节。当然,数组中的偏移量也会缩放8个字节,因此在获取S和T值时不要忘记将其计算出来。