URGENT -- C with inline Assembly, Fscanf a file, getData, Always return overflow - HELP

Hi, I'm having trouble with the following function, getData( ). It's supposed to load an array x with data from file f, returning cursize, the number of elements loaded into x. This getData( ) function will only be called if the filename the user enters is a valid one. Otherwise, the main will just terminates the program. And if the file is opened successfully, then getData will either return a boolean value FALSE (Overflow) or TRUE (Data from the file has been loaded into the X array) back to main. I also include my main below getData( ) function. Overflow should only occur when cursize is larger than maxsize (15) and there is still data in the file that has not been loaded.

The PROBLEM I'M HAVING is that I have the codes compiled successfully, but no matter if it's an empty file, a file with less than 15 integers, or a file with 20 integers (overflow), it ALWAYS says that it's overflowed. Please help.



Boolean getData( FILE* f, int x[], int* cursize, int maxsize )
{
   int hold;
   char format[] = "%d";

   _asm
   {
        mov ebx, x       
        mov esi, cursize            
        mov dword ptr [esi], 0      //cursize = 0      

   Top:
         push esi                              //save ptr to cursize
         push ebx                              //save ptr to x[cursize]
         lea ebx, hold                        //save the address
        push ebx                              //fscanf's 3rd param &d
        lea ebx, format                  //save the format
        push ebx                              //fscanf's 2nd param "%d"

        push f

        call fscanf                        //fscanf(f, "%d", &d)

        add esp, 12                        //clear param off stacks
        pop ebx                              //restore saved registers
        pop esi

        mov eax, hold
        cmp eax, EOF                        //the end of the file yet?
        jne Next                              //if not, keep going       

        mov eax, 1                        //Finish loading, an empty file
        jmp Done                              //return TRUE

   Next:  
        mov ecx, maxsize                   //cursize > 15?
        cmp dword ptr [esi], ecx             //check overflow
        jg Ovfl                              //cursize > maxsize
          mov [ebx], eax                     //x[cursize] stores that value       

        inc dword ptr [esi]                  //cursize++
        add ebx, 4                        //next element
        loop top
   Ovfl:                                    //Not EOF and overflowed
        mov eax, 0                        //return FALSE
   Done:
   }
}

/*THIS IS MY MAIN FUNCTION*/

#define MAX 15

int main()
{
   int SECRET_NUM = 100;  /* WHAT IS THIS FOR?  */
   int x[MAX];
   int cursize;
   int lowest, highest, avg, median;
   FILE* dataFile;      /* internal file pointer for the file */
   char filename[100];  /* string to hold the filename */
   Boolean loadOK;

   /* Ask the user for a filename, then open the data file.
      Be sure to check that the open was successful.
      If not, display a message, and terminate the program.
   */
   printf("Please enter a file name: ");
   scanf("%s", filename);
   dataFile = fopen(filename, "r");

   if ( dataFile != NULL )
   {
      loadOK = getData( dataFile, x, &cursize, MAX );

      /* If the load was not OK, we ran out of room.
         Display a message, and terminate the program.
      */
        if ( loadOK == 0 )
        {
           printf("Fail to load data, OVFL occurred.\n");
         exit(EXIT_FAILURE);
        }

        /* Array loaded successfully */
        else
      {
           /* If there were zero elements in the data file, display a
            message and terminate the program.
           */       
             if ( cursize == 0 )
             {
                  printf("The file is empty. Program terminated\n");
                  exit(EXIT_FAILURE);
             }

             else
             {
                    sortData( x, cursize );                   
                  displayGrades( x, cursize );
                  doStats( x, cursize, &lowest, &highest, &avg, &median );
                  displayStats( cursize, lowest, highest, avg, median );
             }
        }
   }

   else
   {
        printf("Fail to open file.\n");
        exit(EXIT_FAILURE);
   }

   printf("\n\nSECRET_NUM SHOULD BE 100: %d\n", SECRET_NUM);

   return 0;
}


Thanks for any help guys.
PaladinxyzAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
van_dyConnect With a Mentor Commented:
in that case you will just have to  assign TRUE and FALSE in place of 1 and 0, like:

Boolean getData(FILE *f, int *store, int *cursize, int maxsize)
{
            *cursize = 0;
             int i = 0;
              int mynum;
              Boolean ret = FALSE;     //no overflow

              while(fscanf(f, "%d", &mynum) != EOF){
                            if( i >= 15){
                                    ret = TRUE;           //overflow;
                                     break;
                             } else {
                                    store[i] = mynum;
                                    ++i;
                              }
                }
            *cursize = i;
                return ret;
}

make sure you test the return value currectly where u call getData().. like for example .. if somewhere in main()

      if(getData(fp, a, &cur, 15) == FALSE){
         .....//rest of code

By the way, are u supposed to strictly implement this in assembly?
if that is so, consider the option of creating a getData.s file, write the whole
function in assembly(in place of inline), and compile with nasm and later link
to main as required

hope this helps,
van_dy
0
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi Paladinxyz,

I see a couple of things that need tending.  :)

In GetData(), I see the tag 'Top'.  Near the end of the routine I see a jump to 'top'.  I assume that the capitalization got lost and that these are really the same location?

Also in GetData(),  I suggest that you exit the function from within the asm code instead of falling through to the C return.  My assembler is pretty rusty so I can't be as much help here as I'd like.  You can also try to store the return code in a C variable and return the contents of the variable.

It's a hack, I know.  But it should get you past this.  


Good Luck,
Kent

0
 
PaladinxyzAuthor Commented:
Hi, thanks for your suggestion. However, loop 'Top' or 'top' does the same thing. In addition, because getData is supposed to return a boolean value to main, and main should determine if the program should be terminated accroding to that boolean value, so I can't "call exit" inside the assembly code. But thanks for your comment.
0
The Firewall Audit Checklist

Preparing for a firewall audit today is almost impossible.
AlgoSec, together with some of the largest global organizations and auditors, has created a checklist to follow when preparing for your firewall audit. Simplify risk mitigation while staying compliant all of the time!

 
PaladinxyzAuthor Commented:
If no one can do this in assembly, I will also accept an answer in C codes. I just need to have the Boolean getData( FILE* f, int x[], int* cursize, int maxsize ) works.  Meanwhile, I will give my one last shot at the assembly solution. If you guys code it in C or assembler, don't be reluctant to share your views. Thanks!
0
 
stefan73Commented:
Hi Paladinxyz,
There is an Assembly TA. Maybe you should ask to have your question moved there.

Cheers!

Stefan
0
 
PaladinxyzAuthor Commented:
Thanks, I will try to contact him/her now.
0
 
PaladinxyzAuthor Commented:
Did anyone try to write getData( ) in C, or did anyone find my mistake in the assembler codes that caused the constant overflow problem?
0
 
van_dyCommented:
Hi  Paladinxyz,

what is your compiler? that is not the proper
syntax for inline assembly(at least with gcc).
0
 
van_dyCommented:
in C

Boolean getData(FILE *f, int *store, int *cursize, int maxsize)
{
            *cursize = 0;
             int i = 0;
              int mynum;
              Boolean ret = 0;

              while(fscanf(f, "%d", &mynum) != EOF){
                            if( i >= 15){
                                    ret = 1;           //overflow;
                                     break;
                             } else {
                                    store[i] = mynum;
                                    ++i;
                              }
                }
                return ret;
}

hope this helps,
van_dy
                       

             
           
0
 
van_dyCommented:
oh well you may add this before "return ret"
                                  ++i;
                              }
                }
                 *cursize = i;      //to return the current size
                return ret;
}

0
 
PaladinxyzAuthor Commented:
Hi, van_dy, thanks for your suggestion, but right now, the Visual C++ compiler is indicating the following errors:

: error C2143: syntax error : missing ';' before 'type'
: error C2143: syntax error : missing ';' before 'type'
: error C2275: 'Boolean' : illegal use of this type as an expression
\boolean.h(9) : see declaration of 'Boolean'
: error C2146: syntax error : missing ';' before identifier 'ret'
: error C2065: 'ret' : undeclared identifier
: error C2065: 'mynum' : undeclared identifier
: error C2065: 'i' : undeclared identifier
Error executing cl.exe.

This is my Boolean.h

/* FILE: boolean.h
    PURPOSE: Define a boolean type
*/

#ifndef BOOLEAN_H
#define BOOLEAN_H
typedef enum{ FALSE, TRUE } Boolean;
#endif


getData( ) is a function of GradeRoutines.c, and I've already included the following header files:

#include "Boolean.h"
#include <stdio.h>
#include "GradeRoutines.h"

Boolean getData( FILE* f, int x[], int* cursize, int maxsize )
{
   *cursize = 0;
   int i = 0;
   int mynum;
   Boolean ret = 1;

   while(fscanf(f, "%d", &mynum) != EOF)
   {
      if( i >= maxsize)
        {
         ret = 0;           //overflow;
         break;
      }
        else
        {
         x[i] = mynum;
         ++i;
      }
   }
   *cursize = i;                  //*cursize = i;
   return ret;
}
0
 
PaladinxyzAuthor Commented:
Thanks van_dy, the syntax errors are still there, but anyways I appreciate your help. Thanks.

: error C2143: syntax error : missing ';' before 'type'
: error C2143: syntax error : missing ';' before 'type'
: error C2275: 'Boolean' : illegal use of this type as an expression
\boolean.h(9) : see declaration of 'Boolean'
: error C2146: syntax error : missing ';' before identifier 'ret'
: error C2065: 'ret' : undeclared identifier
: error C2065: 'mynum' : undeclared identifier
: error C2065: 'i' : undeclared identifier
Error executing cl.exe.
0
All Courses

From novice to tech pro — start learning today.