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.

ASM > More Beginner Questions

#5744 - bakery2k - Wed May 07, 2003 10:42 pm

I am currently beginning ASM for the GBA. At the moment I am using the GoldRoad assembler. Is this recommended or is there a better one?

I have a few questions:

How do I declare variables in RAM? I obviously need to create byte, word variables etc, but also need to create a few relatively large arrays.

Can I use more than one .asm file to assemble a single program?

When my program is assembled, it contains merely the instructions I wrote. This is loaded into an emulator and runs fine. When I get around to running the code on hardware, do I have to do anything special, such as adding a valid header, or is this done for me?

Finally, when using hardware, what is "multiboot" and how does it differ from whatever is "normal"?

Thanks for your help

#5748 - torne - Thu May 08, 2003 12:12 am

GoldRoad looks pretty easy to use; I use GNU as from devkitadvance, but it's a personal preference thing really.

You declare variables in ram by allocating space in the data or bss sections. I don't know exactly how to do this in GoldRoad as I use GNU as. The data section is for initialised data; i.e. variables that have a starting value, so the GNU as code would look like:
Code:

.data
myvariable:
.byte 0x57

The bss section is for uninitialised data, which will be cleared to zero for you. GNU as code:
Code:

.bss
myvariable:
.skip 1


You can use any number of asm source files for a single program, you will just need to make sure that one of them defines AgbMain.

Does GoldRoad include the crt0.s file? (startup code) If it does, then that will put in the header for you, though most of the values will be blank. To run it on a real GBA you will probably need to patch in the Nintendo logo..etc, which you can do with fuGBAr or similar, though LittleWriter will do this for you. You can't put an ELF binary on the flashcart either; you will need to create a raw binary image. with something like objdump. Again, goldroad might be able to do this.

Multiboot is running code that was downloaded over the link cable, conventionally from a master GBA for things like single gamepak multiplayer, but you can download multiboot compatible programs over a parallel port multiboot cable from your PC. They differ in that they are written to run from ewram, not rom, and they use a different field in the header for their entry point.

Hope that helps,
T

#5783 - bakery2k - Thu May 08, 2003 4:34 pm

Thanks for your reply.

I am now considering moving to GAS, as I cannot find many of the features you mentioned in GoldRoad. Couple this with the fact that GoldRad has not been updated in about a year, and GNU AS seems like a better choice.

Im sure there must be a way to declare variables in RAM, but I cannot see it. There is no mention of AgbMain and startup code is not included, rather the file which you pass to the assembler is assembled as is, nothing is added. Thus I have a horrible feeling that you must use a single source file.

If anyone knows better, please let me know.

Finally, I found easy to follow tutorials using GoldRoad, which is why I started using it. Is there a simple "getting started" tutorial for GNU assembler available anywhere?

#5786 - torne - Thu May 08, 2003 4:58 pm

GNU as's syntax is almost identical, albiet with different special characters. =) There is a quick reference for the assembler directives around somewhere, it's linked from the gbadev docs section. You want to install DevkitAdvance, then. You can get by with just the binutils and core packages, but if you want to be able to use the preprocessor you will need the gcc packages as well.

I think devkitadvance comes with the crt0.s and link scripts; I used the ones available for download elsewhere though as I have customised them somewhat. =)

I don't know of any tutorials specific to GNU as, but the actual assembly code is identical, really, apart from possibly using different (in fact, *standard*.. goldroad is 'wrong') symbols to denote immediate values, comments, and suchlike. The assembler directives are different but all have equivalents.

You will need to use a tool like make, and a Makefile, in order to link your code, unless you are compiling from a single source file in which case you can call it straight through gcc. (yes, gcc can deal with .s/.S input files just as well as C)

If you need any help once you have it all set up, post to this forum some more and I'll see what I can do.

Torne

#7842 - bakery2k - Thu Jun 26, 2003 2:01 pm

I finally got round to installing DevKit Advance and getting some simple projects to work.
I am currently sending my .S files through gcc to assemble, using a batch file containing, for example:

gcc -o simple.elf simple.S
objcopy -O binary simple.elf simple.gba

However, the next thing I need to do is include a binary file which contains values to be used by my code. I think I have to use the linker to do this, as GAS has no .incbin command, but I have no idea how to do it. Can anyone help?

#7874 - tepples - Fri Jun 27, 2003 7:47 am

Write a program that takes a binary file as input and emits a .s file containing constant bytes as output. Or use some sort of appended datafile system.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#7886 - funkeejeffou - Fri Jun 27, 2003 12:14 pm

I'm using goldroad and everything is fine.
To declare variables inRAM, it's easy :
as ewram is 0x2000000, do
start_of_ewram_code ;label of beginning
@textarea 0x2000000
@DBB byte ;variable of 8 bits
0x12 ;value here
@DCW world ;variable of 16 bits
0x5368 ;value here
@DCD ;variable of 32 bits
0xFFFFFFFF ;value here
@ltorg ;split the litteral pool, always do it
@endrarea
end_of_ewram_code ;label of end
Do exactly the same thing for Iwram with a textarea 0x3000000

Then the rest of code and variables will be in ROM

when you start your program, before executing anything else, copy the variables and code in RAM as the textarea are only here to provide the good adresses of the variables but not the location in memory.

mov r0, start_of_ewram_code
mov r1, end_of_ewram_code
mov r2, 0x2000000
copy_data
ldr r3, [r0]+4!
str r3, [r2]+4!
cmp r1, r0
bne copy_data

do the same for iwram.
now when you'll call a variable in your program, it will work as the labels and the location of it will both be ok.

Including file is simple.
Type code in a file, name it file1.asm for example. Now in your main program, just type :
@include file1.asm
this will replace when assembling the include directive by the content of file1.asm, wich is very useful for clarity and the size of the main program.

Goldroad is maybe no more improved, but I really don't see why it should be because everything works fine, and all opcodes have been implemented including ARM and Thumb. That's apparently (I'm new to ASM, just read my forward posts :-) the role of an assembler, translating instructions into binary opcodes. Believe me, I'm writing a 3D engine in Goldroad and all bugs I had came from me and not from the assembler.

By the way, when you compile, Goldroad will generate you a .gba file. Burn it directly to the hardware and it will run (unless your code is buggy). No need to put a valid header.

Well, if you wanna still use GNU, that's your choice of course, but keep in mind that goldroads works well too.

#7892 - tepples - Fri Jun 27, 2003 6:03 pm

Quote:
Goldroad is maybe no more improved, but I really don't see why it should be because everything works fine, and all opcodes have been implemented including ARM and Thumb. That's apparently (I'm new to ASM, just read my forward posts :-) the role of an assembler, translating instructions into binary opcodes. Believe me, I'm writing a 3D engine in Goldroad and all bugs I had came from me and not from the assembler.

Can it generate .o files compatible with GCC? Otherwise, how would somebody write a game of any complexity in 100% assembly language?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#7923 - funkeejeffou - Sat Jun 28, 2003 7:15 pm

Well I guess that some games in the early years were written in entire assembly, as for example, Commander Keen by John Carmack.Besides, even if most games use C or C++, some people like Mickael Abrash write most of their routines in ASM while C is used for only the general structure of the program (succession of the fonctions calls, as the main loop of the engine).
I'm trying to write my entire engine in ASM, and as you've seen me with my newbee questions a month ago, I've been working a lot on it and I guess I've done some progress. With time, ASM coding seems more and more natural, but each line of code must be commented.
I hope I'll make it for the compo, it motivates me a lot !

#8004 - bakery2k - Mon Jun 30, 2003 11:49 am

How do I declare a variable in ewram?
.bss and .data both seem to go into iwram.

#8578 - hzx - Tue Jul 15, 2003 7:38 am

Hi

So, here are my questions on GoldRoad and ARM assembler :)

1. First of all, where can i find proper docs on GoldRoad, including all @commands, etc.?

2. How does the ARM CPU handle signed numbers? Is it similar with the x86 CPUs with the highest bit as the sign?

3. If i use ldr reg, =number instead of mov reg, #number, what is the exact difference? Does ldr load the data from the memory? And if so, why

@define x 10
ldr reg, =x

loads value ten, but

x @DCD 10
ldr reg, =x

loads the address of x?

Thx:
_________________
.hzx

#8662 - Lupin - Thu Jul 17, 2003 2:35 pm

2) Yes, highest bit is sign and negative numbers are inverted

3) There is no difference - just in speed - mov is faster. I don't know the difference between @define and @DCD, but I guess that DCD does declare an REAL variable whilst define is just defining "10"...

#8673 - torne - Thu Jul 17, 2003 7:07 pm

hzx wrote:

3. If i use ldr reg, =number instead of mov reg, #number, what is the exact difference? Does ldr load the data from the memory?


mov reg, #number puts the given number into the register; this only works for certain numbers as there are range limitations. For ARM code, you can use mov to load any constant which can be generated by right-rotating an 8-bit constant by an even number of bits. For Thumb code, you can only load 8-bit constants.

ldr reg, =number does two things: at *compile* time, it puts the value of number into a constant pool; an area near the code designated for storing constants. If you haven't explicitly designated a constant pool, they will go at the end of the file. Then, at runtime, it uses a program-counter relative load to retrieve the number. This means that it can load any 32-bit constant; but it requires one memory access, instead of zero.

hzx wrote:
And if so, why

@define x 10
ldr reg, =x

loads value ten, but


The assembler directive @define does not generate any code (or any bytes at all) - it merely tells the assembler that from this point forward in the current file, the symbol 'x' has the value ten. Thus, ldr reg, =x becomes ldr reg, =10, which loads the value ten via a constant pool as explained above.

hzx wrote:
x @DCD 10
ldr reg, =x

loads the address of x?


This is totally different. The assembler directive @DCD generates words of data. @DCD 10 will put in a four-byte value, ten, at the point in your program where @DCD appears. Prefixing it with an x creates a symbol called x, i.e. a label. Labels get the address of the thing they are labelling, so loading the value x will give you the address of the @DCD. If you doubly indirect, by loading from the loaded value:
ldr r0, =x
ldr r1, r0
then you will get the value stored in x, namely, 10.

These are two different usages. Defining a symbol with @define creates a assemble-time constant. Prefixing anything which is a memory location (such as an instruction, or a data declaration such as @DCD) creates a constant symbol containing that address.

Torne

#8736 - hzx - Fri Jul 18, 2003 7:36 pm

Thanks a lot. Only one more answer needed then: a good and detailed doc on the GoldRoad assembled including the @command descriptions, the way of dividing code into separate files and so on.
_________________
.hzx

#8738 - torne - Fri Jul 18, 2003 8:54 pm

GoldRoad documentation seems to be thin on the ground, and it doesn't seem suited for developing projects which are not a single source file. I would recommend that you try using as, to be honest; it uses 'standard' syntax and outputs ordinary ELF .o files which can be manipulated with a linker or other binary utilities.

Torne