undefined reference in .S file

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
crasher
Posts: 21
Joined: Mon Jan 21, 2008 4:02 am

undefined reference in .S file

Post by crasher »

I wrote a piece of assembly code(start.S) which is listed below.
I tried both
gcc -c start.S
and
start.o:start.S multiboot.h
gcc -c start.S -o start.o

I got error "undefined reference to 'MULTIBOOT_HEADER_MAGIC'"

Does anybody know how to solve this?
FYI multiboot.h is in the same directory as start.S and makefile

#include <multiboot.h>

.text
.global start
start:
jmp __start

.align 4
.long MULTIBOOT_HEADER_MAGIC
....
User avatar
pini
Member
Member
Posts: 26
Joined: Wed Oct 18, 2006 5:12 am
Location: Nancy, France

Post by pini »

Did you try

Code: Select all

.long $MULTIBOOT_HEADER_MAGIC
?

Otherwise, try passing only the preprocessor over your .S file to see what happens
Don't think you can. Know you can.
crasher
Posts: 21
Joined: Mon Jan 21, 2008 4:02 am

undefined reference in .S file

Post by crasher »

I tried just now.
It worked in that the error changed from
"undefined reference ..." to
"no such instruction: typedef struct{'"

It seems the assembler does not recoginze the c instruction.
crasher
Posts: 21
Joined: Mon Jan 21, 2008 4:02 am

undefined reference in .S file

Post by crasher »

When I used gcc -D__ASSEMBLY__ -c start.S,
the "no such instruction.." error and "undefined
reference to MULTIBOOT_HEADER_MAGIC" were gone.

I did not use $MULTIBOOT_HEADER_MAGIC

What is '$' for? I saw some assembly code precedes
constants/macros with '$', such as xen's x86_32.S
while I don't need this in my case.
User avatar
pini
Member
Member
Posts: 26
Joined: Wed Oct 18, 2006 5:12 am
Location: Nancy, France

Post by pini »

Your second error seems quite strange.
I assumed that MULTIBOOT_HEADER_MAGIC was

#define MULTIBOOT_HEADER_MAGIC 0x1BADB002

or something like that.

The '$' sign is used to prefix integer constants in the AT&T assembly syntax.
For instance:

movl $0x10,%eax ; <=> mov eax,0x10 in intel syntax

puts the integer constant 0x10 in eax, while

movl 0x10,%eax ; <=> mov eax,[0x10] in intel syntax

puts the value at memory location 0x10 in eax.
Don't think you can. Know you can.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

For ease of reference, this are the relevant parts of multiboot.h crasher is talking about. (Note that multiboot.h is (C) 1999,2001 FSF Inc., falls under GPL, yadda yadda...)

Code: Select all

     /* Macros. */
     
     /* The magic number for the Multiboot header. */
     #define MULTIBOOT_HEADER_MAGIC          0x1BADB002

     /* ... */
     
     #ifndef ASM
     /* Do not include here in boot.S. */
     
     /* Types. */
     
     /* The Multiboot header. */
     typedef struct multiboot_header
     {
       unsigned long magic;
       unsigned long flags;
       unsigned long checksum;
       unsigned long header_addr;
       unsigned long load_addr;
       unsigned long load_end_addr;
       unsigned long bss_end_addr;
       unsigned long entry_addr;
     } multiboot_header_t;
     
     /* ... */
     
     #endif /* ! ASM */
The statement...

Code: Select all

.long MULTIBOOT_HEADER_MAGIC
...inserts the value 0x1BADB002 at the current position. What does not happen is that a symbol of that name is inserted.

You did cut your code short, so I don't know if you referred to this symbol later on.

As for the "$", it is the qualifier for immediate addressing (constant), as opposed to direct addressing (pointer).

$4 is the value 4.
4 is the value at address 4.

And if you take a look at the header, you will see that the C instructions are commented out if "ASM" is defined. 'as' doesn't know how to handle them.
Every good solution is obvious once you've found it.
crasher
Posts: 21
Joined: Mon Jan 21, 2008 4:02 am

undefined reference in .S file

Post by crasher »

Thanks for your help.
I found '$' precedes an immediate constant operand such as

Code: Select all

movl $0x10, eax 
In the case assgining a memory, we use naked constants, i.e.,

Code: Select all

.long 0x10 
instead of .long $0x10

Am I right?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Yes.
Post Reply