从汇编代码中查找数组的尺寸

时间:2014-05-04 00:56:08

标签: c arrays assembly

我似乎总是把这些类型的问题弄错了。我找出了正确的值,但我总是把它们颠倒过来。对于这个问题,正确的答案是H = 15J = 7,但我像往常一样让它们反转......

有人可以引导我完成他们如何解决这些问题的思考过程吗?

Array indexing.
Consider the C code below, where H and J are constants declared with
#define
.
int array1[H][J];

int array2[J][H];

void copy_array(int x, int y) {

array2[y][x] = array1[x][y];

}

Suppose the above C code generates the following x86-64 assembly code:
# On entry:
# %edi = x
# %esi = y
#
copy_array:

movslq %edi,%rdi

movslq %esi,%rsi

movq %rsi, %rdx

salq $4, %rdx

subq %rsi, %rdx

addq %rdi, %rdx

leaq 0(,%rdi,8), %rax

subq %rdi, %rax

addq %rsi, %rax

movl array1(,%rax,4), %eax

movl %eax, array2(,%rdx,4)

ret

HJ的价值是多少?

谢谢!

2 个答案:

答案 0 :(得分:1)

C和C ++不会将有关数组的信息(除了其地址)传递给函数。

许多其他编程语言都传递数组描述符。

H和J不能通过被调用的函数来确定。

如果您正在寻找此特定实例中的特定值,那么此代码旨在成为一个益智游戏;故意模糊汇编语言。

你需要走完每条指令,弄清楚正在做什么。

例如,如果rsi乘以15,则此序列看起来会将内容相乘。

movq %rsi, %rdx

salq $4, %rdx

subq %rsi, %rdx

逐行浏览。此代码不是为编程而设计的,而是作为某种测试。

答案 1 :(得分:1)

添加评论总是有帮助的。 “技巧”是计算数组元素的地址必须涉及乘以2d数组行长度。你只需要弄清楚那些乘数:

# On entry:
# %edi = x
# %esi = y
copy_array:
movslq %edi,%rdi           ; %rdi = x
movslq %esi,%rsi           ; %rsi = y
movq %rsi, %rdx            ; %rdx = y
salq $4, %rdx              ; %rdx *= 16
subq %rsi, %rdx            ; %rdx -= y (so now %rdx = 15 * y)
addq %rdi, %rdx            ; %rdx += x (so now %rdx = 15 * y + x)
leaq 0(,%rdi,8), %rax      ; %rax = 8 * x
subq %rdi, %rax            ; %rax -= x (so now %rax = 7 * x)
addq %rsi, %rax            ; %rax += y (so now %rax = 7 * x + y)
movl array1(,%rax,4), %eax ; %rax = array1[7 * x + y]
movl %eax, array2(,%rdx,4) ; array2[15 * y + x] = %rax
ret

现在,由于C数组按行主顺序存储,array1的行必须长7个元素(即数组有7列),而array2的行数为15(即它有15个)列)。这意味着你在问题中所说的J = 7和H = 15。