User Name
Password
AppleNova Forums » Programmer's Nook »

x86 Assembly in OS X


Register Members List Calendar Search FAQ Posting Guidelines
x86 Assembly in OS X
Thread Tools
evan
Formerly CoachKrzyzewski
 
Join Date: Jan 2006
Location: Charlottesville, VA
Send a message via AIM to evan  
2010-04-12, 23:45

I'm just trying to get this all working right, it's code provided to us by our professor. He gave us some basic instructions (make sure the function name has an underscore for it, use -f macho) for doing this outside of linux but basically left us on our own an I can't get it to work

Here's my command line inputs and the error message I get, how do I get everything to work nicely so the program behaves normally when I ./vecsum ? The same thing occurs when I use the provided makefile (using -macho), but for simplicity I won't include that.

Code:
Evan-Daviss-iMac:lab8 Evan$ g++ -c -o main.o main.cpp Evan-Daviss-iMac:lab8 Evan$ nasm -f macho -o vecsum.o vecsum.s Evan-Daviss-iMac:lab8 Evan$ g++ -o vecsum main.o vecsum.o ld: warning: in vecsum.o, file is not of required architecture Undefined symbols: "_vecsum", referenced from: _main in main.o ld: symbol(s) not found collect2: ld returned 1 exit status

And here's the code:

vecsum.s
Code:
; vecsum.s ; ; Author : Adam Ferrari ; Date : Jan 29, 1998 ; Purpose : This file contains the implementation of the function ; vecsum, which adds up a vector of integers. ; Modified for NASM by Aaron Bloomfield on 9 Nov 2007 global _vecsum section .text ; ; vecsum ; Parameter 1 - the starting address of a sequence of 32-bit integers. ; Parameter 2 - the number of integers in the sequence. ; Return value - the sum of the integers in the sequence. ; _vecsum: ; Standard prologue push ebp ; Save the old base pointer mov ebp, esp ; Set new value of the base pointer push esi ; Save registers xor eax, eax ; Place zero in EAX. We will keep a running ; sum of the vector elements in EAX. mov esi, [ebp+8] ; Put the vector starting address in ESI. mov ecx, [ebp+12] ; Put the vector size in ECX. We will use ; ECX to indicate how many vector elements ; are left to add into the sum. cmp ecx, 0 ; If there are not more than zero elemen jle vecsum_done ; in the array, skip to the end and return ; zero (already in EAX). vecsum_loop: mov edx, [esi] ; Put the current vector element into EDX. add eax, edx ; Add the current vector element into the ; running sum. add esi, 4 ; Increment ESI to point to the next ; vector element (4 bytes away). dec ecx ; Decrement ECX, the counter of how many ; left to do. cmp ecx, 0 ; If there are more than zero elements jg vecsum_loop ; left to add up, then do the loop again. vecsum_done: ; At this point, the loop is done, and we have the sum of the ; vector elements in EAX, which is exactly where we want the ; return value to be. ; Standard epilogue pop esi ; Restore registers that we used. ; Note - no local variables to dealocate. pop ebp ; Restore the caller's base pointer. ret ; Return to the caller.
main.cpp
Code:
// main.cpp #include <iostream> #include <time.h> #include <cstdlib> using namespace std; extern "C" int vecsum (int *, int); // Purpose: This main program produces a vector of random // numbers between 0 and 99, then calls the // externally defined function 'vecsum' to add // up the elements of the vector. // Author: Adam Ferrari int main () { int n, *vec, sum; cout << "Please enter a vector size: "; cin >> n; // sanity check the vector size if (n <= 0) { cerr << "Vector size must be greater than zero.\n"; return 1; } // allocate, initialize, and display vector vec = new int[n]; // use current time as random seed srand((unsigned) time(NULL)); for (int i = 0; i < n; ++i) { vec[i] = rand() % 100; cout << "\tvec[" << i << "] = " << vec[i] << endl; } // sum up the vector and print out results sum = vecsum(vec, n); cout << "The sum of all vector elements is " << sum << endl; return 0; }
  quote
Majost
monkey with a tiny cymbal
 
Join Date: Nov 2004
Location: Lost
 
2010-04-12, 23:54

That ld warning is the key. I don't know how much you've covered in your class about the stages of compilation, but the linker (ld) goes through the generated object files, figures out where the symbols are, and then properly connects everything into one executable file. It's saying that it can't read your vecsum.o file (not entirely true... but...), and thus it cannot resolve the symbol that's defined inside it.

I Googled asm ld: warning: file is not of required architecture and my top link (which may be biased based on my search history) was this stack overflow question and answer.

Three things here: Warnings are very important. Google is awesome. Stack Overflow is awesome. Learn to use and love them both.

Edit: since I feel guilty about the fib about ld reading vecsum.o.

Compare the difference between the output of file vecsum.o and file main.o. You'll see that they are "formatted" for different architectures. ld needs these files to be of the same architecture to link them together.

Last edited by Majost : 2010-04-13 at 00:08.
  quote
evan
Formerly CoachKrzyzewski
 
Join Date: Jan 2006
Location: Charlottesville, VA
Send a message via AIM to evan  
2010-04-13, 00:26

Quote:
Originally Posted by Majost View Post
That ld warning is the key. I don't know how much you've covered in your class about the stages of compilation, but the linker (ld) goes through the generated object files, figures out where the symbols are, and then properly connects everything into one executable file. It's saying that it can't read your vecsum.o file (not entirely true... but...), and thus it cannot resolve the symbol that's defined inside it.

I Googled asm ld: warning: file is not of required architecture and my top link (which may be biased based on my search history) was this stack overflow question and answer.

Three things here: Warnings are very important. Google is awesome. Stack Overflow is awesome. Learn to use and love them both.

Edit: since I feel guilty about the fib about ld reading vecsum.o.

Compare the difference between the output of file vecsum.o and file main.o. You'll see that they are "formatted" for different architectures. ld needs these files to be of the same architecture to link them together.
thanks! This helped a TON. First I just tried to convert the main.o (which was 64bit) it i386 but then that didn't work, so I had to convert the final vecsum executable file to i386 after converting the other two and it worked well.
  quote
evan
Formerly CoachKrzyzewski
 
Join Date: Jan 2006
Location: Charlottesville, VA
Send a message via AIM to evan  
2010-04-15, 01:56

nm
  quote
Posting Rules Navigation
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Post Reply

Forum Jump
Thread Tools
Similar Threads
Thread Thread Starter Forum Replies Last Post
Assembly evan Programmer's Nook 5 2010-03-25 23:37


« Previous Thread | Next Thread »

All times are GMT -5. The time now is 19:22.


Powered by vBulletin®
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
Copyright ©2004 - 2022, AppleNova