gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > compiling crt0.s

#6944 - Darkain - Wed Jun 04, 2003 10:34 pm

ok, im trying to compile crt0.s, but having no luck at ALL. this is just the first few errors, it goes on for a long time. i went and looked at the file trying to find the problem...

the problem is this:
inside "asm-macros.h" there are some #defines... these #defines dont cause a problem themselves until trying to be used. the asembler is trying to take them in as commands instead of macros.

any ideas on how to fix this?
i read somewhere that the .S in the filename has to be caps in order for it to correctly process macros, but no luck. this didnt fix the problem.

Code:
crt0.S: Assembler messages:
crt0.S:48: Error: bad instruction `function(_start)'
crt0.S:49: Error: bad expression -- `b .Lreal_start//[00]Entry Point'
crt0.S:50: Error: bad instruction `end(_start)'
crt0.S:52: Error: bad instruction `static_object(__crt0_rom_header)'
crt0.S:54: Warning: rest of line ignored; first ignored character is `/'
crt0.S:54: Error: can't open nintendo-logo.S for reading
crt0.S:54: nintendo-logo.S: No error
crt0.S:56: Error: bad expression
crt0.S:56: Warning: division by zero
crt0.S:56: Warning: rest of line ignored; first ignored character is `['
crt0.S:58: Warning: rest of line ignored; first ignored character is `G'
crt0.S:59: Warning: rest of line ignored; first ignored character is `G'
crt0.S:60: Warning: rest of line ignored; first ignored character is `M'
crt0.S:61: Error: bad expression
crt0.S:61: Warning: division by zero
crt0.S:61: Warning: rest of line ignored; first ignored character is `['
crt0.S:62: Error: bad expression
crt0.S:62: Warning: division by zero
crt0.S:62: Warning: rest of line ignored; first ignored character is `['
crt0.S:63: Error: bad expression
crt0.S:63: Warning: division by zero
crt0.S:63: Warning: rest of line ignored; first ignored character is `['
crt0.S:64: Error: bad expression
crt0.S:64: Warning: division by zero
crt0.S:64: Warning: rest of line ignored; first ignored character is `['
crt0.S:65: Error: bad expression
crt0.S:65: Warning: division by zero
crt0.S:65: Warning: rest of line ignored; first ignored character is `['
crt0.S:66: Error: bad expression
crt0.S:66: Warning: rest of line ignored; first ignored character is `['
crt0.S:67: Error: bad expression
crt0.S:67: Warning: division by zero
crt0.S:67: Warning: rest of line ignored; first ignored character is `['
crt0.S:68: Error: bad instruction `end(__crt0_rom_header)'
crt0.S:72: Warning: rest of line ignored; first ignored character is `/'
crt0.S:73: Error: bad instruction `function(_start)'
crt0.S:74: Error: bad instruction `end(_start)'

_________________
-=- Darkain Dragoon -=-
http://www.darkain.com
DarkStar for Nintendo DS

#6955 - Jason Wilkins - Thu Jun 05, 2003 6:23 am

Why did you post about a problem compiling something without providing the command line? (This needs to be in the FAQ, it is so annoying when people say 'this won't compile' without providing a command line.). The only thing I can think of is that you are using 'as' directly.

gcc is the program which knows that a capital S means that it is an assembly file with cpp macros. 'as' knows nothing about this at all.

You should have looked in the Makefile provided, in fact, if you wanted to recompile and install a modified crt0.o, you should have just typed:

make install-crt0

in the crtls directory and it will make all 4 different versions of the crt0.o and install them in the correct location. I know it is not documented, but the Makefile is not very big, so you could have read it ^_^

When you specify the command for gcc, you either have to make sure that you say crt0.S (not crt0.s), AND/OR you have to make sure you supply the -xcpp-with-assembler command line.

If you say crt0.s, because it is windows (and case insensitive) it will find the file, but gcc will think the filename is crt0.s, instead of crt0.S. The capital S tells gcc that the file needs to be run through the c pre-processor.

One thing everyone should remember about devkit advance is that I LOVE to use the compiler driver (gcc or g++) instead of the other tools directly, so you will never see me use ld or as directly and I will always recommend that you use gcc/g++ as well ^_^

If you use 'ld' or 'as' directly, I will need to see a note from your parents giving you permission. Then I will force you to also call cc1 and cc1plus (the real c and c++ compiler programs) directly so you will be consistent. And, while you are at it, use collect2 as well.
_________________
http://devkitadv.sourceforge.net

#6958 - Darkain - Thu Jun 05, 2003 7:10 am

:D hahahaa, thanx alot!!

well, i first tried make on the makefile, cause i saw that there. andit turns out, my copy of GCC/DKA doesnt have a MAKE.EXE (unless its somewhere other than DKA\Bin - just as a note, im on r5-beta3). so, since i got MSVC installed, i atemped to use NMAKE on it, but this was also a pain, and errored all over.

so yea, then i finally searched around the web... tons of web sites said to use "as -mthumb-interwork -o crt0.o -c crt0.S" or something along the lines of this. so yea, i tried, and horribly failed.

i didnt realize that GCC/G++ would work w/ ASM like it does for compiling C/C++ and linking.


yay! now i dont have to be stuck w/ a horribly small stack when working w/ interupts now.

(and on a side note, getting into GBA development has been a very interesting learning experience, after being a MSVC junkie for soooo long)
_________________
-=- Darkain Dragoon -=-
http://www.darkain.com
DarkStar for Nintendo DS

#6966 - Jason Wilkins - Thu Jun 05, 2003 2:38 pm

I'm not sure how you didn't end up with make.exe, it is either in the devkitadv/ or devkitadv/tools directory, and that should be in the path if you use cmd-rc.bat to start a command line.

Actually, there is a feature which allows you to change the stack locations without modifying crt0.S

You can override the values of __sp_usr_initial_value and __sp_irq_initial_value without modifying them in crt0.S

You do this by declaring them in your code somewhere and initializing them to the desired value.

Like this:

Code:

__attribute__ ((section(".cartrom.data"))) int *__sp_usr_initial_value = (int*)(0x02040000 - 0x500);


It is put in the .cartrom section so that it will not be put into RAM. The stack is initialized before any values are copied to RAM, so if it was in work RAM, then it would contain garbage at the time it is needed.
_________________
http://devkitadv.sourceforge.net


Last edited by Jason Wilkins on Thu Jun 05, 2003 9:27 pm; edited 1 time in total

#6986 - Darkain - Thu Jun 05, 2003 7:50 pm

this worked... after some time. i had to play around w/ the numbers a bit..

0x020040000 is invalid...
0x02040000 is what worked.


is there a way i could just get usr and irq to share stacks? or, i guess my main question is, if i use new/malloc, its technically global at that point, so wich stack would it go on? im asuming that it would be dependant if i am in an irq handler or not.

basically, what i want is this... i want the majority of my code in irq handlers, this way i can halt the cpu upon idle. so, since most of the code is in irq handlers, this is where the larger stack should be. but at the same time, there are going to be a few global things as well, and i was just wondering what the best way to handle this is.

(btw: i unpacked all the files again, and i now have the make.exe... not sure why it wasnt there before)
_________________
-=- Darkain Dragoon -=-
http://www.darkain.com
DarkStar for Nintendo DS

#6990 - tepples - Thu Jun 05, 2003 8:43 pm

Darkain wrote:
i want the majority of my code in irq handlers, this way i can halt the cpu upon idle.

You can halt the CPU upon idle with the VBlankIntrWait BIOS call.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#6993 - Darkain - Thu Jun 05, 2003 8:46 pm

tepples wrote:
Darkain wrote:
i want the majority of my code in irq handlers, this way i can halt the cpu upon idle.

You can halt the CPU upon idle with the VBlankIntrWait BIOS call.


yea, i know, i am already doing this, but i had several issues with even the simplest of functions in my irq handler code because of stack space restrictions.
_________________
-=- Darkain Dragoon -=-
http://www.darkain.com
DarkStar for Nintendo DS

#6998 - Jason Wilkins - Thu Jun 05, 2003 9:38 pm

You can either put your stack at an absolute address that you know is big enough to hold it (like how I did in the example above, placing it near the end of ewram), or you can put it in an array like this:

Code:

#define IRQ_STACK_ENTRIES 1000
__attribute__ ((section(".ewram.data"))) int my_irq_stack[IRQ_STACK_ENTRIES];
__attribute__ ((section(".cartrom.data"))) int *__sp_irq_initial_value = &my_irq_stack + IRQ_STACK_ENTRIES;


Doing it this way makes sure that the stack will not corrupt the heap. There is code to prevent the heap from corrupting the stack, but not visa-versa. That means that a maloc might fail because it would have corrupted the stack, but nothing is checking to make sure that the stack does not grow down and overwrite dynamic memory.

I am thinking of implementing two functions for DKA's low level library:

Code:

void call_with_stack(void (func*)(), int *stack);
void call_with_stack_no_return(void (func*)(), int *stack);


The first function would be useful for dynamically allocating a huge stack and doing some complicated, greedy, recursive function, then going back to the standard, smallish stack when finished. The second would be useful for situations where you just want to throw away the stack and start over, or switch to a different mode of operations.

I'm not sure how useful the no_return version would be, it might be better to use the set long jump function or exception handling.
_________________
http://devkitadv.sourceforge.net