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.

C/C++ > C++ and Assembly?

#11175 - ken2 - Sun Sep 28, 2003 6:21 am

I use DevKitAdvance and was wondering how to put assembly in along with C code? I know you can do it, I just havent found a tutorial or explanation for it. Probably just my beginner-ness though.

By Assembly with C code, imean like a program thats mainly C code, but has some assembly code in for doing various stuff. not sure about this ARM command THUMB stuff, haven't done assembly for GBA before, but i've done assembly on another processor before.

#11176 - sajiimori - Sun Sep 28, 2003 6:50 am

You can either use inline assembly (which has some quirks), or use seperate source files that are pure assembly code (which I'd recommend).

Anything that is so speed-critical that it needs to be in assembly should also be written in 32-bit ARM instructions, and stored in IWRAM.

Make a .S file for all your assembly stuff, and set it up something like this:
Code:

.section .iwram
.arm

.global function_abc
.align 2
function_abc:
   // do stuff
   bx lr

.global data_xyz
.align 2
data_xyz:
   .word 1234

Then link it in, and you can call the functions from C code.

#11197 - ken2 - Sun Sep 28, 2003 9:11 pm

How would I go about calling the .s file function from C, and also how would I go about linking the .s into my gcc makefile for devkitadvance?

#11200 - NEiM0D - Sun Sep 28, 2003 10:22 pm

Going forth from mr. Sajimori's code comments, here's what you would put in C to use it:
Quote:

extern void function_abc(void);
extern short data_xyz;


Cheers.

#11232 - sajiimori - Mon Sep 29, 2003 6:06 pm

"gcc -c" compiles, "gcc -o <outfile> <objfiles>" links. Nothing new here...

#11275 - torne - Wed Oct 01, 2003 12:21 am

sajiimori wrote:
Anything that is so speed-critical that it needs to be in assembly should also be written in 32-bit ARM instructions, and stored in IWRAM.


I wouldn't say that was always true; GCC's Thumb code generation needs work, and you can beat it for performance without needing ARM opcodes if you know what you're doing. =)

#11281 - sajiimori - Wed Oct 01, 2003 2:52 am

Quote:

GCC's Thumb code generation needs work, and you can beat it for performance without needing ARM opcodes if you know what you're doing.

You're right of course. My point was that if the code is so speed-critical that you're thinking about hand-coding it in assembly, there's little reason *not* to use 32-bit ARM code and put it in IWRAM (unless you're out of IWRAM, but hand-coded assembly is usually very compact).

#11285 - torne - Wed Oct 01, 2003 10:34 am

Not everything can be done faster in ARM, especially if you have many clever tricks *grin*. Also, my only GBA code at the moment is for an OS, and I desperately need to reserve almost every last byte of RAM for applications. =)

#11287 - tepples - Wed Oct 01, 2003 2:43 pm

torne wrote:
Not everything can be done faster in ARM, especially if you have many clever tricks *grin*

Care to share some of these "clever tricks" in a tutorial about efficient Thumb coding? Or do you prefer to keep them a trade secret for now?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11291 - torne - Wed Oct 01, 2003 4:54 pm

*grin* Sounds like a plan. I've been meaning to write some programming tutorial bits for gbadev for a while; the most important being a guide to the ARM procedure call standard (or: Why Can't I Make Calls To Asm Functions From C Work Properly). You (or other people) might want to read the value synthesis macros that I talked about, though, which I wrote in this thread originally (my first posts, too!): http://forum.gbadev.org/viewtopic.php?t=154

If you are using non-default wait state settings you will need to tune the macros to make the right tradeoffs, but if you have the default settings it should be fine and guarentees always to be at least as fast as an ldr r0, =whatever instruction. The ARM analogous version of the macros are fairly obvious, though I've not actually written them (not used any significant ARM code in my project yet); I'll write them for my tutorial.

Note that in ARM it's normally best to access IO registers by loading 0x4000000 into some register then using preindexed offsets to reach them (unless they are beyond 0x40000FF of course). Making this kind of decision through a macro is unfortunately not possible; though it would be possible to make my high-level assembler do it. Not that I've written it yet. =)

#11293 - DekuTree64 - Wed Oct 01, 2003 5:33 pm

Yeah, it does seem like the ASM forum gets a lot of things that could be answered by the APCS.
But I want clever tricks^_^ THUMB is fun, and you can usually get things to time out to where values are in the right regs at the right time so only having 2 ops per instruction doesn't cause problems, but sometimes it's just plain messy. But then if you look at it it almost always takes less actual bytes than ARM, even if you do have to go through a lot of instructions to do something simple.
Still, I'd like to hear some stuff from someone with a lot of experience. Just call it an advanced tutorial (for lack of an equivalent, punless word), and then you can make it quick and to-the-point, and be more relaxed while writing it cause anyone reading it should have enough sense not to blindly follow any mistakes you might make from not spending hours on it.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#11294 - torne - Wed Oct 01, 2003 5:44 pm

I'll spend some time on it soon; right now I'm moving from one room to another in a kind of musical chairs thing at university as they cock up my accomodation arrangements multiple times consecutively. =)

Once the world is less hectic I'll try and share some tips.

#11785 - Tinyn - Sat Oct 18, 2003 9:59 pm

How would I code some ASM function so that it can accept arguments from a C/C++?

#11787 - tepples - Sat Oct 18, 2003 10:22 pm

Tinyn wrote:
How would I code some ASM function so that it can accept arguments from a C/C++?

First four arguments are passed in r0-r3. The rest are passed on the stack, as described in ARM-Thumb Procedure Call Standard (PDF).
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11788 - DekuTree64 - Sat Oct 18, 2003 10:24 pm

Again, this can easily be answered by the APCS. The first up to 4 arguments are passed in r0-r3, and any over that are pushed onto the stack. They go in ascending order from sp/r13, so say you have 7 args, it would go like this:
r0-r3 = arg0-arg3, [sp] = arg4, [sp, #4] = arg5, [sp, #8] = arg7.

edit: Tepples beat me to it^^
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku