why doesnt this work? heres a c line that im trying to convert to inline asm.



int avg = (video[i-1] + video[i+1] +video[i+320] + video[i])>>2;


when i replace that with the following code, it doesnt work right



int avg = 0;
__asm
{
xor eax, eax
mov eax, video[i]
add eax, video[i+1]
add eax, video[i-1]
add eax, video[i+320]
shr eax, 2
mov avg, eax
}
Posted on 2002-01-25 00:57:36 by gregd
gregd,

In "C" what's the type of "video"?

if video's data type is char, convert like this:

mov al, byte ptr video

otherwise

mov ax, word ptr video

...

if "video" is structure, you must convert properly...
Posted on 2002-01-25 01:42:35 by muzidowa
Thanks, sorry i should have mentioned that video was a pointer to an unsigned short.
Posted on 2002-01-25 12:17:48 by gregd
To translate C subscripting, evaluate the subscript, scale it, then add the base address of the array. The x86 requires the alterable portion of the address to be in a register.

Let's correct the following:

add eax,video

The total index value must be scaled, and the values used must be in a register, we use ECX to avoid corrupting the running total in EAX:

ecx = i + 32
add eax,video[2*ecx] ; Registers can only be scaled by 1, 2, 4, or 8

Translating the first line:

mov ecx,i
add ecx,32
add eax,video[2*ecx]

This is the kind of code a nonoptimizing compiler might produce.

We can get better results by translating the following equivalent code:
register ushort *p = &video[i]; // translates to [b]p = video + i[/b]

avg = (p[-1] + p[1] + p[320] + p[0]) >> 2;
	; Notice the scaling of indexes (subscripts)

mov edx,i
lea ecx,video[2*edx] ; Create address (pointer)
xor eax, eax
add ax, [ecx-2*1]
add ax, [ecx+2*1]
add ax, [ecx+2*320]
add ax, [ecx]
shr ax, 2
mov avg, eax
Posted on 2002-01-25 16:23:12 by tank