windows - passerer arrays til funktioner i x86 asm

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg lærer x86 asm og bruger masm, og jeg forsøger at skrive en funktion, der har den tilsvarende signatur til følgende c-funktion:


void func(double a[], double b[], double c[], int len);


Jeg er ikke sikker på, hvordan man implementerer det?


ASM filen bliver kompileret til en win32 DLL.


Så jeg kan forstå, hvordan man gør dette, kan nogen venligst oversætte denne meget enkle funktion til asm for mig:


void func(double a[], double b[], double c[], int len)
{
  // a, b, and c have the same length, given by len
  for (int i = 0; i < length; i++)
    c[i] = a[i] + b[i];
}


Jeg forsøgte at skrive en funktion som denne i C, kompilere den og se på den tilsvarende adskilte kode i exe ved hjælp af OllyDbg, men jeg kunne ikke engang finde min funktion i den.


Mange tak.

Bedste reference


Jeg har ikke skrevet x86 i et stykke tid, men jeg kan give dig en generel ide om, hvordan man gør det. Da jeg ikke har en assembler handy, er dette skrevet i notesblok.


func proc a:DWORD, b:DWORD, c:DWORD, len:DWORD

  mov eax, len
  test eax, eax
  jnz @f
  ret

    @@:

  push ebx
  push esi

  xor eax, eax

  mov esi, a
  mov ebx, b
  mov ecx, c

    @@:

  mov edx, dword ptr ds:[ebx+eax*4]
  add edx, dword ptr ds:[ecx+eax*4]
  mov [esi+eax*4], edx
  cmp eax, len
  jl @b

  pop esi
  pop ebx

  ret  

func endp


Ovennævnte funktion er i overensstemmelse med stdcall og er omtrent, hvordan du ville oversætte til x86, hvis dine argumenter var heltal. Desværre bruger du dobbeltværelser. Sløjfen ville være den samme, men du skal bruge FPU-stakken og opkoderne til at lave det aritmetiske. Jeg har ikke brugt det i et stykke tid og kunne ikke huske instruktionerne fra toppen af ​​mit hoved desværre.

Andre referencer 1


Du skal overføre hukommelsesadresserne til arrays. Overvej følgende kode:


.data?
array1 DWORD 4 DUP(?)

.code
         main PROC

                      push LENGTHOF array1
                      push OFFSET array1
                      call arrayFunc             
         main ENDP

         arrayFunc PROC
                                   push ebp
                                   mov ebp, esp
                                   push edi

                                   mov edi, [ebp+08h] 
                                   mov ecx, [ebp+0Ch]
                                   L1:

                                  ;reference each element of given array by [edi]
                                  ;add "TYPE" *array* to edi to increment
                                   loop L1:
                                   pop edi
                                   pop ebp
                                   ret 8
         arrayFunc ENDP
         END main


Jeg har lige skrevet denne kode for at forstå konceptet. Jeg overlader det til dig at finde ud af, hvordan du korrekt regner med brugen af ​​registre for at nå dit programs mål.