• C

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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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
INTRODUCING: WatchGuard's New MFA Solution

WatchGuard is proud to announce the launch of AuthPoint, a powerful, yet simple, Cloud-based MFA service designed to eliminate the vulnerabilities that put your data, systems, and users at risk.

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
van_dyCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.