ASM register management

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sat Jul 26, 2008 8:58 pm

furrykef wrote: Speaking of words versus bytes, there's a quirk in the M68k that I never realized until I thought about it this morning. Suppose I want to deliberately modify only half of a word:

Code: Select all

    move.b #0, d0               ; Overwites LSB
    move.b #0, TwoByteVariable  ; Overwrites MSB!
How counterintuitive! If you always use 16-bit writes, you avoid the problem.
Chilly Willy wrote:Yeah, I use something like that.
What do you use?

- Kef
Sorry, that was a mis-type - it should read "I'd use", not "I use". :oops:

And you hit on the one major advantage of little-endian over big-endian - no matter the size of the int, a pointer always points at the LSB. Some programmers utilitize that without realizing it's different in BE systems. Those programming quirks are REAL hard to find when porting.

tomaitheous
Very interested
Posts: 256
Joined: Tue Sep 11, 2007 9:10 pm

Post by tomaitheous » Sat Jul 26, 2008 11:42 pm

furrykef wrote: I don't think it's quicker, because, looking at the instruction counts, there are no instructions where a word is processed faster than a byte.
I was referring to defining byte type variables in the assembler. Having them in sequence, you're going to hit an address penalty on the odd addressed ones.

furrykef
Interested
Posts: 30
Joined: Mon Jul 21, 2008 7:28 pm

Post by furrykef » Sat Jul 26, 2008 11:46 pm

Hmm. I wasn't aware there was such a penalty. Thanks.

HardWareMan
Very interested
Posts: 746
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Sun Jul 27, 2008 4:21 am

tomaitheous wrote:
furrykef wrote: I don't think it's quicker, because, looking at the instruction counts, there are no instructions where a word is processed faster than a byte.
I was referring to defining byte type variables in the assembler. Having them in sequence, you're going to hit an address penalty on the odd addressed ones.
If you try access to word or long word at odd address you will get Address Error exception. You can put your Address Error exception handler routine and do something usefull.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Jul 27, 2008 7:31 am

tomaitheous wrote:
furrykef wrote: I don't think it's quicker, because, looking at the instruction counts, there are no instructions where a word is processed faster than a byte.
I was referring to defining byte type variables in the assembler. Having them in sequence, you're going to hit an address penalty on the odd addressed ones.
There's no penalty on accessing bytes on odd addresses. I think you meant that if at some point you converted a byte variable into a word or long, you would then run into the odd address violation on the 68000. Just want to make sure people don't get confused and start putting bytes on even addresses thinking it's faster. :D

furrykef
Interested
Posts: 30
Joined: Mon Jul 21, 2008 7:28 pm

Post by furrykef » Sun Jul 27, 2008 8:11 am

In that case the situation is exactly as I thought it was... so then there would be no sense in which words are faster than bytes.

- Kef

tomaitheous
Very interested
Posts: 256
Joined: Tue Sep 11, 2007 9:10 pm

Post by tomaitheous » Sun Jul 27, 2008 8:22 am

Sorry, I meant accessing them(byte) with a word instruction.

furrykef
Interested
Posts: 30
Joined: Mon Jul 21, 2008 7:28 pm

Post by furrykef » Sun Jul 27, 2008 8:27 am

I'm not sure why you'd want to access a byte using a word access, unless you're operating on multiple bytes at a time, in which case you probably have already aligned the start of the table or whatever anyhow.

- Kef

tomaitheous
Very interested
Posts: 256
Joined: Tue Sep 11, 2007 9:10 pm

Post by tomaitheous » Sun Jul 27, 2008 9:00 am

furrykef wrote:I'm not sure why you'd want to access a byte using a word access, unless you're operating on multiple bytes at a time, in which case you probably have already aligned the start of the table or whatever anyhow.
- Kef
Using a word base instruction by accident.

furrykef
Interested
Posts: 30
Joined: Mon Jul 21, 2008 7:28 pm

Post by furrykef » Sun Jul 27, 2008 9:31 am

I think if you're using a word instruction with a byte in RAM, you have bigger problems... namely, loading/storing a garbage byte. Not to mention that loading a word from an odd boundary isn't slower, it's flat-out illegal (unless you write an appropriate exception handler as HardWareMan said, but I'd rather just write proper code in the first place).

So I still don't understand what exactly you're getting at...

- Kef

TmEE co.(TM)
Very interested
Posts: 2443
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Sun Jul 27, 2008 9:33 am

As long as you're not accessing Words and Longs from odd addresses, you're fine... this gave me some headache, as only Regen emulates Address Error exception (but regen is too slow and a bit buggy to use)...
You can make some use of Address Error exception as HWM said.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

cdoty
Very interested
Posts: 117
Joined: Wed Nov 29, 2006 2:54 pm
Location: Houston, TX
Contact:

Post by cdoty » Fri Aug 01, 2008 12:40 am

Chilly Willy wrote:NEVER put anything on the stack if you have a free register. The more you keep stuff in registers, the faster it will be. That's the ENTIRE REASON to do anything in assembly. If you're going to use the stack, you might as well just use C.

NEVER arbitrarily save/restore registers. This goes back to using the stack. If you're going to just push/pop all the registers in every routine, you might as well be using C. You're an ASSEMBLY LANGUAGE programmer - act like it. Use any registers you can, NEVER save/restore unless FORCED to by the need to put something else in a register when no more are free.

NEVER make "prologues" or "epilogues". Again, that goes back to arbitrarily using the stack. Again, if you're going to use them in your functions, might as well be using C.
A lot of this sounds like optimizing too early. I would rather write the routines, and make sure they work. Then, when I need the speed, I'll go back and pick at the routines to remove unused pushing/popping and try to fit data into registers. Granted, I do initially try to get as much into registers as possible. And, we all know that no-one writes the 'perfectly' optimized routine the first time, it takes a few times over to really optimize it.

This is what I did on the CDi (68000), SNES (65816), and FM-Towns (x86) versions of Frog Feast.
Chilly Willy wrote:A program with several hundred thousand lines is just like one with a few thousand... just longer. :lol:
Especially if you manage/organize routines and files correctly.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Fri Aug 01, 2008 2:26 am

I don't think of it as "optimizing", I think of it as "writing in assembly" as opposed to "pretending you're a C compiler". :wink:

It's a philosophical difference. 8)

furrykef
Interested
Posts: 30
Joined: Mon Jul 21, 2008 7:28 pm

Post by furrykef » Fri Aug 01, 2008 5:06 pm

At the end of the day, only two questions really matter:

1) Is the program free of bugs?
2) Does the program run fast enough to get everything done on every frame?

As long as the answer to both questions is "yes", how you go about programming is irrelevant, really. It doesn't matter if your code is "slow" if you're not dropping frames. So my inclination is to take the approach that is least likely to result in bugs, then optimize if my code is not fast enough -- "make it right, then make it fast."

I have to admit I still don't get this "thinking in assembly" concept. I get the general idea of it but I don't really know how to apply it. Perhaps I need to find some illustrative examples.

- Kef

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Fri Aug 01, 2008 6:33 pm

"Thinking in assembly" probably comes from lots of work in assembly. C was for mainframes when I first started out. We didn't even have it available - it was assembly or BASIC or Forth or nothing. Eventually, we started to see small-C on 8 bit systems... I can remember when I got Deep Blue C for the Atari and thought "why would anyone use this instead of assembly?" :lol:

It's the difference in being fluent in a language and being able to converse in a language, but with a heavy accent.

Post Reply