assemblyhla

Why return wrong results this program?


I recently started working with HLA and I can't find the error in this code. Please help me someone. Why return wrong results this program? The program is complete without any syntax error, but return bad values.

procedure program(VAL i:int32; VAL j:uns16; VAL N:uns32; VAR tomb: int32); @cdecl; @use EAX; @returns("EAX"); @external;
procedure program(VAL i:int32; VAL j:uns16; VAL N:uns32; VAR tomb: int32); @nodisplay;
begin program;
// tomb[0]=i+(j*9);
// for (k=1; k<N; k++) tomb[k]=(tomb[k-1]+9)*j;
// sum=0;
// for (k=0; k<N; k++) sum=sum+tomb[k]/15+i-j;
// return sum;

  PUSH(EBX);
  PUSH(ECX);
  PUSH(EDX);
  PUSH(EDI);
  PUSH(ESI); 

//Tomb[0]
  MOVZX(j,EAX); 
  INTMUL(9, EAX);
  ADD(i, EAX);
  MOV(tomb,EDI);
  MOV(EAX, [EDI]);  
  MOV(EAX, ESI); 
  MOV(N, ECX);

for1:
  DEC(ECX);         //ECX = ECX - 1
  JZ for1_end;      //if ECX = 0,
  ADD(9, ESI);      //ESI = (tomb[k-1]+9)
  INTMUL(j, ESI);   //ESI = (tomb[k-1]+9)*j
  ADD(4, EDI);  
  MOV(ESI, [EDI]);  //tomb[k] = tomb[k]=(tomb[k-1]+3)*j
  JMP for1;
for1_end:

//for (k=0; k<N; k++) sum=sum+tomb[k]/15+i-j;
  SUB(ESI, ESI);    // ESI (sum) = 0
  MOV(tomb, EDI);   // EDI = tomb cime
  MOV(N, ECX);      // ECX = N
  MOVZX(j, EDX);
  MOV(15, EBX);     
  ADD(i, EBX);
  SUB(EDX, EBX);    //15+i-j

for2:
  MOV( [EDI], EAX );// EAX = tomb[k]
  CDQ;
  IDIV( EBX );      // EAX = tomb[k]/15+i-j
  ADD( EAX, ESI );  // ESI = ESI+tomb[k]/15+i-j
  ADD(4, EDI);
  DEC(ECX);         // ECX = ECX-1
JNZ for2;           // if ECX=0,

  MOV( ESI, EAX );      // EAX = sum
  POP( ESI );
  POP( EDI );
  POP( EDX );
  POP( ECX );
  POP( EBX );
end program;

EDIT:

The N and tomb not visible for me. From i and j all i can-->

1. test case (i=7830, j=348):   result(for me):-15984526, correct:-1700110054 
2. test case (i=7830, j=913):   result(for me):-669363,   correct:-231479087 
3. test case (i=7830, j=3475):  result(for me):4404210,   correct:963858517 
4. test case (i=7830, j=-6588): result(for me):-674954,   correct:1719334650 
5. test case (i=7830, j=29684): result(for me):-6505388,  correct:-1490170292

Solution

  • // for (k=0; k<N; k++) sum=sum+tomb[k]/15+i-j;
    

    Given this expression, it's wrong to calculate 15+i-j and use that as a divider using IDIV( EBX ); // EAX = tomb[k]/15+i-j !

    Normal rules of algebra dictate that you need to divide by 15 and later on add i and subtract j.