#166932 - sverx - Tue Feb 24, 2009 11:06 am
Hi!
let's imagine you've got somebody who already knows ASM programming on a different system (say the x86).
What this person should read to start his approach to ARM assembler? Online resources links very welcome :) Starting from what's inside an ARM processor is advised ;)
Thanks from that person who needs it ;)
_________________
libXM7|NDS programming tutorial (Italiano)|Waimanu DS / GBA|A DS Homebrewer's Diary
#166933 - Dwedit - Tue Feb 24, 2009 11:10 am
Download the source code to something written in ARM ASM and try to add features to it. If you look at surrounding code, you can very quickly pick up which instructions are used for the various tasks. I learned ARM by hacking PocketNES.
Also, grab this file:
http://www.eecs.umich.edu/~panalyzer/pdfs/ARM_doc.pdf
Even though it's really old, and doesn't have inline hyperlinks, it's a very good document.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#166934 - eKid - Tue Feb 24, 2009 11:14 am
GBATek has a friendly reference (in my opinion) of the instruction set. The official ARM docs contain more technical info for their processors.
#166948 - sverx - Tue Feb 24, 2009 5:06 pm
Dwedit wrote: |
Also, grab this file |
reading it, seems very interesting...
see you soon! ;)
_________________
libXM7|NDS programming tutorial (Italiano)|Waimanu DS / GBA|A DS Homebrewer's Diary
#168116 - sverx - Fri Apr 10, 2009 2:21 pm
Replying to this old topic of mine because the question I'm going to ask it's somehow related to this 3d...
So, when I write C code, it's better if I use int instead of, for instance, u8 or u16, when I need 'temporary' variables? I mean, say I need to repeat a task some 200 times:
Code: |
u8 i;
for(i=0;i<200;i++)
do_something(); |
will the compiler produce better code if I declare that variable int, instead of u8? Or am I wrong and it's the same?
Thanks :)
EDIT: lol... funny, this is exactly the 200th post of mine on this forum... and I didn't notice before!!! :D :D
#168131 - Dwedit - Fri Apr 10, 2009 6:18 pm
Yep, if you use u8, the compiler will throw in AND 255 every time it stores it into the variable. You want to use ints.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#168137 - Ruben - Fri Apr 10, 2009 8:37 pm
Not necessarily "and r0, r0, #255" since you could be in THUMB mode or, for some odd reason using s8..
Though it depends on the compiler, most compilers will try to keep the code to exactly what you told it; that is, keep it to 8-bits for u8, 16 for u16, etc.
If I remember right, THUMB, in uN, will use lsl/lsr pairs or simply a preloaded register and an and instruction. For sN, however, I think it *has* to use lsl/asr pairs, unless it's s32, in which case the sign bit doesn't need to be extended.
For ARM, if it can, it will use an immediate mask, use a preloaded register and a mask, be silly and clear the bits manually (see TTE) or use LSL/ASR/LSR pairs.
EDIT:
So yeah, in summary, int = good, u8/u16 = bad.
#168152 - sgeos - Sat Apr 11, 2009 3:23 pm
Ruben wrote: |
So yeah, in summary, int = good, u8/u16 = bad. |
Unless you absolutely need u8 or u16.
#168153 - Ruben - Sat Apr 11, 2009 3:58 pm
.. That too :P
Though.. you may get away with using u/s32 and casting to u/s8/16 if the need arises, only when it's necessary (as in, so the compiler doesn't do creepy stuff)
Ok, rephrase time :P
You may be able to get away with using 32-bits all the time and typecast when you must (like adding 2x 8-bit variables into a 16-bit one)
#168189 - sverx - Tue Apr 14, 2009 9:32 am
Thanks! :) Good explanations :)
#168411 - sverx - Tue Apr 28, 2009 10:00 am
Another question... again about writing 'better' C code keeping in mind where's the code going to run (NDS, in this case)
Do I obtain better code if I declare variables "very locally" (meaning declaring it only if I'm going to use it and as close as possible to the moment I'm going to use it) ?
For example, if I write
Code: |
if (<condition1>) {
int i;
for (i=0;i<200;i++)
doSomething1();
}
doSomethingE();
if (<condition2>) {
int i;
for (i=0;i<200;i++)
doSomething2();
} |
will (would?) the compiler make better code than
Code: |
int i;
if (<condition1>) {
for (i=0;i<200;i++)
doSomething1();
}
doSomethingE();
if (<condition2>) {
for (i=0;i<200;i++)
doSomething2();
} |
Thanks in advance for your comments :)
#168420 - Dwedit - Tue Apr 28, 2009 8:23 pm
I've seen compilers change this:
int row=0;
some_function(row,"text 1");
row++;
some_function(row,"more text");
row++;
some_function(row,"even more text");
row++;
into this:
some_function(0,"text 1");
some_function(1,"more text");
some_function(2,"even more text");
Whenever you ask about what compilers do, always use the -S option to see what it does.
However, always declare a local copies of global variables if you know they won't be modified outside this function. Whenever you do a function call, the compiler has to assume that all global variables may change before the function returns, so it will re-read the variable between function calls. Keeping a local copy makes the compiler know your intention better, so it may save it in the registers instead of rereading it.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#168429 - Ruben - Wed Apr 29, 2009 3:18 am
Oo, I know that~
If you don't want the compiler doing that, use -fno-peel-loops, I think. Loop peeling is when it fully unrolls a loop.
#168435 - sverx - Wed Apr 29, 2009 10:30 am
Dwedit wrote: |
Whenever you ask about what compilers do, always use the -S option to see what it does. |
That's interesting... anyway my question was more on the side of "how to write better C code", I still do not have enough knowledge to compare two ASM sources and judge... :|
Dwedit wrote: |
However, always declare a local copies of global variables if you know they won't be modified outside this function. Whenever you do a function call, the compiler has to assume that all global variables may change before the function returns, so it will re-read the variable between function calls. Keeping a local copy makes the compiler know your intention better, so it may save it in the registers instead of rereading it. |
Sorry, I really can't get what you mean :| How can a global be modified outside the function I'm in? :| What can change a global variable before the function returns? I'm missing something important? :| :| :|
#168437 - Ruben - Wed Apr 29, 2009 11:12 am
For example..
Code: |
for(int i = 0 ; i < 512 ; i++) {
u32 MyVal1 = SomeSrc[2] * 45;
u32 MyVal2 = SomeSrc[2] * 87;
} |
Usually, the compiler will perform 2 loads, just to be sure they won't get modified (by interrupts, for example). By preloading, you can make sure it won't do that.
Code: |
for(int i = 0 ; i < 512 ; i++) {
u32 MyVal0 = SomeSrc[2];
u32 MyVal1 = MyVal0 * 45;
u32 MyVal2 = MyVal0 * 87;
} |
EDIT: Please delete multiple posts if they appear.. they are accidental, because my internet hasn't been working nicely.
#168453 - Dwedit - Wed Apr 29, 2009 2:07 pm
More like
Code: |
int what_i_selected;
void some_function
{
if (what_i_selected==5)
foo();
if (what_i_selected==2)
bar();
if (what_i_selected==8)
foobar();
}
|
what_i_selected needs to be reloaded every time. If you made a local copy, it won't be.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#168460 - sverx - Wed Apr 29, 2009 4:27 pm
Cool, I didn't know that, thanks both. But... ok, globals could change because of an interrupt, but why locals won't? Because they're in the stack, I guess, but I'm not really sure that this is the reason...
Stack is also faster than main ram on a NDS, right?
And how can you do that thing:
Code: |
for(int i = 0 ; i < 512 ; i++) {
... |
? My compiler always stops and say I can't declare that variable there!!! I'm using devKitPro, latest version...
Thanks! :)
I believe I really have to move my topics to the "Beginner" section... forgive my many questions, but you all have got a lot of good answers, and it just makes me more curious...
#168461 - kusma - Wed Apr 29, 2009 4:30 pm
sverx wrote: |
And how can you do that thing:
Code: | for(int i = 0 ; i < 512 ; i++) {
... |
? My compiler always stops and say I can't declare that variable there!!! I'm using devKitPro, latest version...
|
That's C++ code. The C-way of doing this is
Code: |
int i;
for(i = 0 ; i < 512 ; i++) { |
I hope this helps.
#168463 - sverx - Wed Apr 29, 2009 4:35 pm
kusma wrote: |
That's C++ code. The C-way of doing this is ... [...] |
AHAHAHAHAH... ops ;) Please delete my post... all of them ;)