# What does the code do?

Challenge #64

What does this code do?

An array of `array[x][y]` form is accessed here. Try to determine the dimensions of the array, at least partially, by finding y.

``````_array\$ = 8
_x\$ = 12
_y\$ = 16
_f  PROC
mov eax, DWORD PTR _x\$[esp-4]
mov edx, DWORD PTR _y\$[esp-4]
mov ecx, eax
shl ecx, 4
sub ecx, eax
lea eax, DWORD PTR [edx+ecx*8]
mov ecx, DWORD PTR _array\$[esp-4]
fld QWORD PTR [ecx+eax*8]
ret 0
_f  ENDP
``````

At first I think there is a mistake in the question. Because I only see three variables here, one for array address, the one x and one y, so I assume it's actually a 2d array of double, not a 3d as in "An array of `array[x][y]`".

Then I was stuck because eventually the program loads `array[8y+192x]`, and x and y can be anything.

So I figured this must be a 3d array of double, with the third dimension given. I still couldn't figure it out so I tried to write my own program and use Godbolt to give me assembly. After a few trials I got something pretty close to the original program:

Something close

However I'm still having difficulty to match my program with the original question. I think I'm pretty close but how do I proceed from here? I have a hunch that y is also 24 in the original question, but not 100% sure.

This is somewhat of a symbolic simplification. If you execute code from start of the procedure, then just before ret these are the relevant changes to the state of the program - ignoring registers

``````float_st0          = @64[array + (y + x * 0x78) * 0x8]
float_stack_ptr    = float_stack_ptr + 0x1
``````

where `st0` has been loaded with a 64bit value from a location.

``````array + (y + x * 0x78) * 0x8
``````

In a 1D array the way you access any index is

``````array + index * sizeof(member)
``````

The size of the array member is 8 `sizeof(double)` here so the index is

``````y + x * 0x78
``````

2D arrays are laid out linearly in memory. Accessing second dimension requires the size of first dimension to be known - In the above example to access `array` we need to access it like

``````array + sizeof(int) * (2 + 1 * 3)
``````

In the op `x` is getting multiplied by 0x78 - so the size of the `y` dimension is 0x78 members.

Additionally I could replicate the problem code to an extent here

With this code and x86 MSVC v19.0, optimization flag /Ox

``````double load(double array[][0x78], int x, int y) {
return array[x][y];
}
``````

we get

``````_array\$ = 8                                   ; size = 4
_x\$ = 12                                                ; size = 4
_y\$ = 16                                                ; size = 4
mov     ecx, DWORD PTR _x\$[esp-4]
mov     eax, DWORD PTR _y\$[esp-4]
shl     ecx, 4
sub     ecx, DWORD PTR _x\$[esp-4]
lea     ecx, DWORD PTR [eax+ecx*8]
mov     eax, DWORD PTR _array\$[esp-4]
fld     QWORD PTR [eax+ecx*8]
ret     0