Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 427
  • Last Modified:

nasm in c - trouble writing c functions in nasm

This is the code:

;;printRecords.asm
bits 32
extern printf

segment .data
   RSIZE db 12
   INTSIZE db 4
   CHARSIZE db 1

segment .text
   global _printRecords

_printRecords:
   pusha
   mov EBP,ESP
   
   mov EDX,[EBP+8]      ; *R
   mov ECX,[EBP+12]     ; num_recs
   dec ECX              ; loop prep
   mov EBX,[EBP+16]     ; sizeof(R)
   xor EAX,EAX

loop_start:
   cmp EAX,ECX
   je loop_end
   push EDX
   call printf
   add ESP,4
   add EDX,EBX
   jmp loop_end

loop_end:
   mov ESP,EBP
   popa
   ret

;;record_cl.h
/*
// record_cl.h
// A definition of the Record class
// John Stewart
*/

#include <iostream>
#include <string>
using namespace std;

#ifndef RECORD_CL_H
#define RECORD_CL_H

class Record {
   public:
      int Id;
      int Age;
      int Sex;
};

#endif

;;record_search.cpp
/*
record_search.cpp
A command-line program to search Records
John Stewart
Last modified: 12/3/2003
*/

#include <iostream>
#include <cstdio>
#include <string>
#include <fstream>
#include "record_cl.h"
using namespace std;

int numRecords (string);
void loadData (string, int, Record []);
void printRecords (Record [], int, int);
bool searchRecord (Record [], int, int);

int main () {
   string fn = "rec_data.txt";
   int num_recs = numRecords(fn);
   int s_age = 0;
   bool found_one = false;

   Record *R;
   Record *S;
   R = new Record[num_recs];
   loadData(fn, num_recs, R);
   printRecords (R, num_recs, sizeof(S));

   cout << "Enter search age: ";
   cin >> s_age;
   found_one = searchRecord(R, num_recs, s_age);

   delete [] R;
}

int numRecords (string fil) {
   ifstream file("rec_data.txt");
   int num;
   file >> num;
   file.close();
}

void loadData (string fn, int num, Record* rec) {
   ifstream file("rec_data.txt");
   file >> rec[0].Id;
   
   for (int i = 0; i < num; i++) {
      file >> rec[i].Id;
      file >> rec[i].Age;
      file >> rec[i].Sex;
   }

   file.close();
}

;;searchRecord.asm
bits 32
extern printf

segment .data
   RSIZ db 12
   NFOUND db "No match found",0
   FOUND db "User ID: %d",0xA,"Age: %d","Sex: %s",0xA,0xA,0

segment .text
   global _searchRecord

_searchRecord:
   pusha
   mov EBP,ESP

   mov ESI,[EBP+8]         ; *R
   mov EDX,[ESI]
   xor EAX,EAX

loop_start:
   cmp EAX,[EBP+12]        ; [EBP+12] = num_recs
   je loop_end
   add EDX,4
   cmp EDX,[EBP+16]      ; [EBP+16] = s_age
   je print_it
r: add EDX,RSIZ
   sub EDX,4

   inc EAX
   jmp loop_start

print_it:
   push dword [EDX]
   push dword [EDX+4]
   push dword [EDX+8]
   push FOUND
   call printf
   add ESP,16
   jmp r

loop_end:
   mov ESP,EBP
   popa
   mov EAX,1
   ret

;;Makefile
record_search: searchRecord.o printRecords.o record_search.o
      g++ -o record_search searchRecord.o printRecords.o record_search.o
record_search.o: record_search.cpp
      g++ -c record_search.cpp
searchRecord.o: searchRecord.asm
      nasm -f elf searchRecord.asm
printRecords.o: printRecords.asm
      nasm -f elf printRecords.asm
clean:
      rm -f *~
      rm -f *.o
      rm -f record_search
all:
      make clean
      make

Here is the linker error:
record_search.o(.text+0x148): In function `main':
: undefined reference to `printRecords(Record*, int, int)'
record_search.o(.text+0x185): In function `main':
: undefined reference to `searchRecord(Record*, int, int)'
collect2: ld returned 1 exit status
make[1]: *** [record_search] Error 1
make[1]: Leaving directory `/home/stewart/project2'
make: *** [all] Error 2

I know there are other bugs, but this one eludes me.  I prototyped the functions, and coded them in assembly, and compiled the asm before the .c, and no go.  Why is this error being generated?
0
stubuf612
Asked:
stubuf612
  • 5
  • 3
  • 3
1 Solution
 
cookreCommented:
I'm not familiar with g++ or NASM, but it looks like you're declaring the entry point _printRecords but referring to printRecords.  Does g++ prepend the _?

same for _searchRecord
0
 
stubuf612Author Commented:
Nope, same compile error.
0
 
cookreCommented:
extern void printRecords (Record [], int, int);
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
stubuf612Author Commented:
nope.... same error
0
 
cookreCommented:
Given my lack of familiarity with these, anything else is pure speculation.  

All I can think of now is bypassing make and doing a manual link (make generating a flakey link?, yeah, sure)
0
 
sunnycoderCommented:
>: undefined reference to `printRecords(Record*, int, int)'
>record_search.o(.text+0x185): In function `main':
>: undefined reference to `searchRecord(Record*, int, int)'
>collect2: ld returned 1 exit status

Linker was not able to locate definitions for the above mentioned functions .. i.e. while you have declared the functions, they have not been defined
0
 
stubuf612Author Commented:
well.... no... because I defined them in printRecords.asm and searchRecord.asm!!!
0
 
stubuf612Author Commented:
perhaps incorrectly, but still, they are defined in those asm files (the whole point)
0
 
stubuf612Author Commented:
Ah.... I've discovered the answer:

 extern "C" void printRecords (Record [], int, int);

That language type specification was the trick, but now a segmentation fault... argh!
0
 
sunnycoderCommented:
run it through gdb
0
 
sunnycoderCommented:
If you wish to, you can post in community support and seek refund for this question.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now