Well, that worked. Thanks Paul for the detailed explanation! Much appreciated. And thanks to everyone else also for their ideas! You guys are great! :) --- In , "Paul B. Webster" <paulb@m...> wrote: > On Sat, 2004-11-06 at 17:36, nimish_sudan wrote: > > But after I added these new lines of code, the assembler started > > giving the error Branch out of Range. > > Nothing to do with memory or over-writing code. It means exactly what > it says - it's trying to tell you you are attempting to branch to a > place that is too far away for a signed 8-bit displacement - the > relative branches (including all the conditional ones) use a single byte > as the value. > > Thanks Darren, but the branch is -128 to +127, and it's relative to > the *next* instruction, since the signed value is added to the program > counter *as well as* the normal stepping of the program counter. IIRC. > > > So what I did was this: > > > > LOOP1 > > LDAA .... > > ... > > ... > > BRA LOOPTRICK > > ... > > LOOPTRICK BRA LOOP1 (trying to trick it) > > You tricked yourself - you made the *new* branch *even further*. The > "trick", if you wish to do this, is to do it like this: > > LOOP1 > > LDAA .... > > ... > > ... > > > LOOPTRICK BRA LOOP1 (trying to make the jump *nearer*) > > > ... > > ... > > BRA LOOPTRICK > > This divides the branch into two parts, each smaller than the original, > but you now have to branch *past* "LOOPTRICK". > > Now this is actually wasteful - in the case of an unconditional branch > - because you simply code a JMP instead, allowing you to go anywhere in > the code space, but perfectly sensible for a conditional branch. > > Quite often however, this is avoided by re-structuring the code. The > situation you describe is a "WHILE ... DO" loop (generally the same as a > DO ... WHILE, depending on how you interpret it). That is, of the > structure: > > <Initialisation> > LOOP1: > <Set up a test> > <Do the test, i.e., flags are set> > BRANCH_IF EXIT1 > <Body of iteration> > BRANCH LOOP1 > > EXIT1: > <next part of program> > > One suggestion that Darren made, was to ensure the loop is compact, by > making the body of the iteration, a subroutine which is simply *called* > inside the loop. This may come unstuck if you place the subroutine > between the branch and the "EXIT1", because the extra overhead of the > subroutine may now make the conditional branch too far. > > On the other hand, if you place the subroutine at the start of the > code (a common convention, with a "JMP START" as the first instruction > of all, to skip over all the subroutines, or simply vector to the actual > start location rather than the start of code memory), then you have to > use JSR rather than BSR and you are limited in building relocatable > modules. > > Usually it helps (because it speeds execution by the delay of the > branch for each iteration) to re-organise the code thus: > > <Initialisation> > BRANCH ENTRY1 > > LOOP1: > <Body of iteration> > ENTRY1: > <Set up a test> > <Do the test, i.e., flags are set> > BRANCH_IF_NOT LOOP1 > <next part of program> > > And sometimes it turns out that the body of the iteration is something > you really wanted to do as part of the initialisation anyway, or you can > allow to do it by a different initialisation, so that you don't need to > branch into it - you actually turn it into a "DO UNTIL" loop that only has > one branch. This is no faster than the "branch-entry" version, but may > sometimes save code space. > > So there. > -- > Cheers, > Paul B. |