Actually the range of a branch is -128 to +127. One other quirk in 68HC11 coding is that if you need to conditionally branch to some where far away, then you have to branch over a jump instruction using the opposite condition. Like this: BNE SKIP JMP GOBACK ; You really wanted a branch on equal SKIP ... ----- Original Message ----- From: "Darren" <> To: <> Sent: Saturday, November 06, 2004 2:41 AM Subject: RE: [m68HC11] Branch out of Range > > Hi Nimish > > Branch only has an 8 bit range, you will have to change > how you do things. Change the code use more subroutines or > use a jump instead. > > Branch is +128 to -127 if I remember correctly. > > Welcome to assembly... hehe > > Darren Moore > > > -----Original Message----- > > From: nimish_sudan [mailto:] > > > > > > Hey guys, another question here. I've got a program which originally > > worked fine. I then added some lines of code to it, which also work > > fine by themselves. But after I added these new lines of code, the > > assembler started giving the error Branch out of Range. > > I then tried logically to see why the BRA function would not work. > > So what I had was: > > > > LOOP1 > > LDAA .... > > ... > > ... > > BRA LOOP1 <-- it would give error here > > .... > > > > So what I did was this: > > > > LOOP1 > > LDAA .... > > ... > > ... > > BRA LOOPTRICK > > ... > > LOOPTRICK BRA LOOP1 (trying to trick it) > > > > I was just trying different things and discovered that the error now > > was being displayed at the LOOPTRICK line. I also found out that if > > I comment a few random lines of code, the error would no longer > > appear. I'm kind of new to assembly, so I'm approaching this from a > > C++ stand point. Is this some sort of memory issue? Seems to me that > > I am somehow overwriting the code in memory which is why the error > > disappears when I comment out a few lines. > > Any help would be appreciated! > > Yahoo! Groups Links > ************************************************************** > Scanned by VisNetic MailScan for SMTP Servers. > Visit http://www.deerfield.com/products/visnetic_mailscan. > ************************************************************** > |
Re: Branch out of Range
Started by ●October 30, 2004
Reply by ●November 6, 20042004-11-06
Hey guys, another question here. I've got a program which originally worked fine. I then added some lines of code to it, which also work fine by themselves. But after I added these new lines of code, the assembler started giving the error Branch out of Range. I then tried logically to see why the BRA function would not work. So what I had was: LOOP1 LDAA .... ... ... BRA LOOP1 <-- it would give error here .... So what I did was this: LOOP1 LDAA .... ... ... BRA LOOPTRICK ... LOOPTRICK BRA LOOP1 (trying to trick it) I was just trying different things and discovered that the error now was being displayed at the LOOPTRICK line. I also found out that if I comment a few random lines of code, the error would no longer appear. I'm kind of new to assembly, so I'm approaching this from a C++ stand point. Is this some sort of memory issue? Seems to me that I am somehow overwriting the code in memory which is why the error disappears when I comment out a few lines. Any help would be appreciated! |
|
Reply by ●November 6, 20042004-11-06
Hi Nimish Branch only has an 8 bit range, you will have to change how you do things. Change the code use more subroutines or use a jump instead. Branch is +128 to -127 if I remember correctly. Welcome to assembly... hehe Darren Moore > -----Original Message----- > From: nimish_sudan [mailto:] > Hey guys, another question here. I've got a program which originally > worked fine. I then added some lines of code to it, which also work > fine by themselves. But after I added these new lines of code, the > assembler started giving the error Branch out of Range. > I then tried logically to see why the BRA function would not work. > So what I had was: > > LOOP1 > LDAA .... > ... > ... > BRA LOOP1 <-- it would give error here > .... > > So what I did was this: > > LOOP1 > LDAA .... > ... > ... > BRA LOOPTRICK > ... > LOOPTRICK BRA LOOP1 (trying to trick it) > > I was just trying different things and discovered that the error now > was being displayed at the LOOPTRICK line. I also found out that if > I comment a few random lines of code, the error would no longer > appear. I'm kind of new to assembly, so I'm approaching this from a > C++ stand point. Is this some sort of memory issue? Seems to me that > I am somehow overwriting the code in memory which is why the error > disappears when I comment out a few lines. > Any help would be appreciated! |
Reply by ●November 6, 20042004-11-06
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. |
|
Reply by ●November 7, 20042004-11-07
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. |