Page 1 of 1
undefined reference in .S file
Posted: Mon Jan 21, 2008 4:14 am
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
....
Posted: Mon Jan 21, 2008 4:24 am
by pini
Did you try
?
Otherwise, try passing only the preprocessor over your .S file to see what happens
undefined reference in .S file
Posted: Mon Jan 21, 2008 4:34 am
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.
undefined reference in .S file
Posted: Mon Jan 21, 2008 5:00 am
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.
Posted: Mon Jan 21, 2008 6:36 am
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.
Posted: Mon Jan 21, 2008 7:10 am
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...
...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.
undefined reference in .S file
Posted: Mon Jan 21, 2008 7:46 pm
by crasher
Thanks for your help.
I found '$' precedes an immediate constant operand such as
In the case assgining a memory, we use naked constants, i.e.,
instead of .long $0x10
Am I right?
Posted: Tue Jan 22, 2008 2:23 am
by JamesM
Yes.