Reply by Anders Lindgren September 17, 20032003-09-17
Jonathan Kirwan <jkirwan@jkir...> writes:

> Chapter 9 of the MSP430 Application Report Book
discusses how to
> code PC-relative calls, this way:
>
>       MOV PC, Rn        ; Address SC+2 > Rn
>       ADD #SUBR$, Rn   ; Add offset (SUBR  (SC+2))
>       CALL Rn           ; SC+2+SUBR(SC+2)) = SUBR
>
> As you can see, this uses 4 words, 7 cycles, and scratches a
> register.

There is an alternative way.  If you perform the call like the
following:

   PUSH PC                  # 2 bytes
   ADD.W #foo-($+4), PC     # 4 bytes

And the return:

   ADD.W #0x4, 0(SP)        # 4 bytes
   RET

Then you will get a slightly better result.  At first sight it looks
like this is more expensive, but in real life it isn't.  Why?  Well,
because most applications will tend to have a lot more call points
than returns.  In this case we will gain two bytes on each call point,
which makes up for the four bytes we lose at each return.  In
addition, we doesn't have to worry about allocating the extra register
Rn that the TI code requires.

This, by the way, is what the position independent code model in the
IAR compiler uses.

    -- Anders

Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.

Beginning Microcontrollers with the MSP430

Reply by onestone September 17, 20032003-09-17
Jonathan Kirwan wrote:
> On Wed, 17 Sep 2003 17:06:41 +0930, Al wrote:
> 
> 
>>nOT BEING ONE TO BE CONTROVERSIAL OR ANYTHING ;@}. But I don't see
what 
>>all the fuss is about, frankly I've never missed it. The current 
>>implementation of CALL LABEL produces a call to the address at the 
>>contents of address LABEL, neat! easy to undertsand an dvery useful.
> 
> 
> Oh, Al.  Don't you remember the days, toggling in the code where
> ever you could fit it, your calluses rubbing a little sore from
> the toggling?  And if its not position independent and you
> started off wrong by one, you get to toggle it all in again?
> And, of course, it's easier to memorize a block of binary code
> than to have to keep the nasty little fields in your head as you
> hand toggle it in.
> 
> Hehe.

I don't know about that. All my early stuff was hand keyed, but very 
early on the Army paid for about 500 xeroxed sheets of programming 
papaer. I basically designed a format that let me easily calculate the 
binaries for each instruction. Again, perhaps my early designs were too 
crude, but, although the address was set to autoincrement after each 
entry I also had address increment and decrement buttons (incidentally 
the mechanism that taught me the hard way about debouncing), so it was 
easy to correct a mistake. Of course you had to spot it, but hey, 
debugging was fun. You could also read back the memory contents from 
0000, That was my A#1 debug tool!! later, when I moved to mainframes 
there were banks of piano key toggle switches for program and data 
entry, but I never even contemplated meorising other than the very few 
main operands, the rest was just a case of knowing the bit-fields, which 
was the bit I found easy.

> 
> 
>>two instances, one where a machine might require field upgrades, or 
>>where the same machine might have multiple personalities depending on 
>>who the client is. In this case LABEL might be in data flash, so by 
>>simply compiling with different subroutine names/addresses at this 
>>location we have a universal program with split personalities. Or a 
>>system that can be upgraded, leaving a comms core behind that always 
>>re-enters the new version of the program with CALL NEWPROG. This gets 
>>around a lot of the constraints you often ghave to meet with field 
>>upgrading software. You often end up having to fix a lot of entry and 
>>exit points. This method re-enters run time code through a single 
>>address, whose contents are re-programmable, and exits to upgrade mode 
>>using a simple RET to the protected (hopefully) software in the upgrade 
>>procedures.
>>
>>Even more useful than that perhaps. If now LABEL is a RAM address we 
>>have a very simple way of executing task lists, priority scheduling etc.
>>
>>I can't think why I might HAVE to use PC relative addressing, when
there 
>>might be other options. In fact it is something I've rarely used
for any 
>>instructions on any micro.
> 
> 
> But there is a use for PIC (position independent code) or two,
> perhaps.  Add-in extension routines may be downloaded from
> RS-232 and placed in the next available slot, and the assembler
> won't know where that is.  They access the target O/S via
> absolute addressing, but access their own subroutines via PIC.
> I'm sure I could cobble up some other reasons, too.
> 
> You are just too used to compile-and-burn mode.  ;)

I don't work that way necessarily, My code doesn't have holes in it 
except explicit holes designed for bolt in routines. Since the address 
of these is jknown it's simply enough to set an ORG and compile. I 
rarely have to upgrade in bits at a time. Most upgrades I do are either 
trivial, or major overhauls.

> 
> 
>>The anomolous operation isn't in fact with the way CALL works, it
works 
>>the same way that MOV	LABEL,r4 works.
> 
> 
> I completely understand that, Al.  It basically means that they
> didn't think beyond what they were already doing, long enough to
> realize a quick 'mind shift' would have made a useful address
> mode out of a useless one.

But I don't find it useless, far from it, I use it more than I have ever 
used a PC relative call.


> 
> 
>>It is JMP LABEL that appears to 
>>have the wrong syntax, in fact all of the jump instructions only have PC

>>relative addressing, totally contrary to the syntax for all other 
>>instructions. I bemoan the loss of other addressing modes for jumps 
>>rather than the omission of a dubious PC relative call. I mean JMP 
>>#LABEL is how it appears to work right now, but JMP (LABEL) (the default

>>syntax for other isntrcution sis indirect addresssing) would be useful, 
>>as would JMP Rn, JMP @Rn etc without having to jump ;^) through hoops to

>>achieve the same effect, as in ADD LABEL,PC, or ADD &LABEL,PC, or
ADD 
>>#LABEL,PC, or ADD @R5+,PC. These are PC relative jumps, in effect, with 
>>out the range limit.
> 
> 
> Too wrapped up in the assembler stuff, Al.  I'm thinking machine
> code and you are thinking assembler, here.

Really the same thing at the end of it, and it is at the machine code 
level that the micro ended up flawed, and at the assembler level that 
compensation must be made. It seems that the designers were either 
overwhelmed by the desire for a large jump range, or underwhelmed by too 
much schnapps. The basic JMP and condition codes require only 6 bits, 
the remaining 10 bits have all been assigned as WORD OFFSET, that really 
shows how befuddled they might have been.  How deviant, Now the 
assemblers task is even quirkier, and it almost precludes the use of the 
MSPs conventional syntax, since the value fields there are 'natural', 
that is the value generated by the assembler is the absolute value 
implied by the source code, MOV #1234H sees the value 1234H in the 
second word of the operand, MOV 1234H sees the MOV indirect opcode 
appear in the first word of the operand, and the offset to the address 
1234H appear in the second word. Only the jumps differ in this respect, 
and I think it was a kludgy design to avoid a short jmp, and to give jmp 
a longer range, therefore I am suggesting that the designers required 
extra, and perhaps dedicated jmp processing hardware. I did start 
tracking the instruction set decode mechanism some months back (I was 
laid up and had nothing better to do) and IIRC I came to the conclusion 
then that the designers had kludged the jump, but don't remember where I 
went after that. Had they maintained the the conventional format of the 
instruction set they woudl have ended up with 8 variants of jump, with 
an offset of just 256 bytes, not convenient when using word addresses, 
since -128 /+127  sort of becomes restrictive, in reality a range of -64 
to +62 instructions, with +127 being handled as a special case. It seems

that rather than use a 2 word operand, and thus, presumably increase the 
number of clock cycles a jump required, they chose the klunky method we 
now know and love. On balance the two word operand jump would have been 
more flexible. In this case you could have taken several paths, perhaps 
steal 1 more bit to indicate a very short jump, as is extremely common 
in loops, with the address in the remaining 7 bits, or a very long jump 
using a second word. But then we don't need that, the BR emulated 
instruction can do that. The concern may simply have been to improve 
overall execution speeds, but in my experience JMP is mostly used to 
travel very short distances, and, certainly the places where shaving 2 
instruction cycles off execution would nearly alwsy fit this case. So 
throw away the knlunky jump and revert IT rather than make another 
special case out of CALL.

>>Perhaps I'm just warped and twisted, or
maybe it's because I never had 
>>to suffer the PDP11 ;@}
> 
> 
> hehe.  You wouldn't consider it suffering, Al.  I guarantee you
> that with a couple of adjustments on the MSP430 architecture by
> little ole me and you'd be even more pleased with the result.
> You'd never look back on any facet of it.  (And I wouldn't use a
> single additional inverter or transmission gate to get there.)

I had some experience with various MODCOMPs, which I was told were PDP 
based, didn't like tham 1 bit, but then us knuckle draggers are prone to 
be pedants.

Cheers

Al


Reply by Jonathan Kirwan September 17, 20032003-09-17
On Wed, 17 Sep 2003 17:06:41 +0930, Al wrote:

>nOT BEING ONE TO BE CONTROVERSIAL OR ANYTHING ;@}.
But I don't see what 
>all the fuss is about, frankly I've never missed it. The current 
>implementation of CALL LABEL produces a call to the address at the 
>contents of address LABEL, neat! easy to undertsand an dvery useful.

Oh, Al.  Don't you remember the days, toggling in the code where
ever you could fit it, your calluses rubbing a little sore from
the toggling?  And if its not position independent and you
started off wrong by one, you get to toggle it all in again?
And, of course, it's easier to memorize a block of binary code
than to have to keep the nasty little fields in your head as you
hand toggle it in.

Hehe.

>two instances, one where a machine might require
field upgrades, or 
>where the same machine might have multiple personalities depending on 
>who the client is. In this case LABEL might be in data flash, so by 
>simply compiling with different subroutine names/addresses at this 
>location we have a universal program with split personalities. Or a 
>system that can be upgraded, leaving a comms core behind that always 
>re-enters the new version of the program with CALL NEWPROG. This gets 
>around a lot of the constraints you often ghave to meet with field 
>upgrading software. You often end up having to fix a lot of entry and 
>exit points. This method re-enters run time code through a single 
>address, whose contents are re-programmable, and exits to upgrade mode 
>using a simple RET to the protected (hopefully) software in the upgrade 
>procedures.
>
>Even more useful than that perhaps. If now LABEL is a RAM address we 
>have a very simple way of executing task lists, priority scheduling etc.
>
>I can't think why I might HAVE to use PC relative addressing, when
there 
>might be other options. In fact it is something I've rarely used for
any 
>instructions on any micro.

But there is a use for PIC (position independent code) or two,
perhaps.  Add-in extension routines may be downloaded from
RS-232 and placed in the next available slot, and the assembler
won't know where that is.  They access the target O/S via
absolute addressing, but access their own subroutines via PIC.
I'm sure I could cobble up some other reasons, too.

You are just too used to compile-and-burn mode.  ;)

>The anomolous operation isn't in fact with the
way CALL works, it works 
>the same way that MOV	LABEL,r4 works.

I completely understand that, Al.  It basically means that they
didn't think beyond what they were already doing, long enough to
realize a quick 'mind shift' would have made a useful address
mode out of a useless one.

>It is JMP LABEL that appears to 
>have the wrong syntax, in fact all of the jump instructions only have PC 
>relative addressing, totally contrary to the syntax for all other 
>instructions. I bemoan the loss of other addressing modes for jumps 
>rather than the omission of a dubious PC relative call. I mean JMP 
>#LABEL is how it appears to work right now, but JMP (LABEL) (the default 
>syntax for other isntrcution sis indirect addresssing) would be useful, 
>as would JMP Rn, JMP @Rn etc without having to jump ;^) through hoops to 
>achieve the same effect, as in ADD LABEL,PC, or ADD &LABEL,PC, or ADD 
>#LABEL,PC, or ADD @R5+,PC. These are PC relative jumps, in effect, with 
>out the range limit.

Too wrapped up in the assembler stuff, Al.  I'm thinking machine
code and you are thinking assembler, here.

>Perhaps I'm just warped and twisted, or maybe
it's because I never had 
>to suffer the PDP11 ;@}

hehe.  You wouldn't consider it suffering, Al.  I guarantee you
that with a couple of adjustments on the MSP430 architecture by
little ole me and you'd be even more pleased with the result.
You'd never look back on any facet of it.  (And I wouldn't use a
single additional inverter or transmission gate to get there.)

:)

Jon

Reply by onestone September 17, 20032003-09-17
nOT BEING ONE TO BE CONTROVERSIAL OR ANYTHING ;@}. But I don't see
what 
all the fuss is about, frankly I've never missed it. The current 
implementation of CALL LABEL produces a call to the address at the 
contents of address LABEL, neat! easy to undertsand an dvery useful.

two instances, one where a machine might require field upgrades, or 
where the same machine might have multiple personalities depending on 
who the client is. In this case LABEL might be in data flash, so by 
simply compiling with different subroutine names/addresses at this 
location we have a universal program with split personalities. Or a 
system that can be upgraded, leaving a comms core behind that always 
re-enters the new version of the program with CALL NEWPROG. This gets 
around a lot of the constraints you often ghave to meet with field 
upgrading software. You often end up having to fix a lot of entry and 
exit points. This method re-enters run time code through a single 
address, whose contents are re-programmable, and exits to upgrade mode 
using a simple RET to the protected (hopefully) software in the upgrade 
procedures.

Even more useful than that perhaps. If now LABEL is a RAM address we 
have a very simple way of executing task lists, priority scheduling etc.

I can't think why I might HAVE to use PC relative addressing, when there 
might be other options. In fact it is something I've rarely used for any 
instructions on any micro.

The anomolous operation isn't in fact with the way CALL works, it works 
the same way that MOV	LABEL,r4 works. It is JMP LABEL that appears to 
have the wrong syntax, in fact all of the jump instructions only have PC 
relative addressing, totally contrary to the syntax for all other 
instructions. I bemoan the loss of other addressing modes for jumps 
rather than the omission of a dubious PC relative call. I mean JMP 
#LABEL is how it appears to work right now, but JMP (LABEL) (the default 
syntax for other isntrcution sis indirect addresssing) would be useful, 
as would JMP Rn, JMP @Rn etc without having to jump ;^) through hoops to 
achieve the same effect, as in ADD LABEL,PC, or ADD &LABEL,PC, or ADD 
#LABEL,PC, or ADD @R5+,PC. These are PC relative jumps, in effect, with 
out the range limit.

Perhaps I'm just warped and twisted, or maybe it's because I never had

to suffer the PDP11 ;@}

Al

Jonathan Kirwan wrote:
> On Tue, 16 Sep 2003 17:59:37 -0000, Noah wrote:
> 
> 
>>>>A good question - it's an inconsistency in the syntax - if
I had
>>
>>designed it,
>>
>>>>I would have made call the same as jmp, and used something like
>>>>
>>>>        call    @fptr
>>>>
>>>>for indirect function calls.
>>>>...
>>>
>>>IMHO, I think it's a mistake. This means you cannot have PC
relative
>>
>>calls. 
>>
>>I don't think that's true.  According to the Users' Guide
(SLAU049C),
>>you can get a PC-relative call with `call LABEL'.  This works
>>correctly with the GNU assembler; do other assemblers disallow it?
> 
> 
> There isn't a single instruction on the MSP430 which yields a PC
> relative call behavior.  I think it was a sad oversight on their
> part (or Horst Diewald's part.)
> 
> It takes 7 cycles, 4 instruction words, and a spare register for
> computation in order to make a PC-relative function call.  It's
> possible that GNU assembler hides these details, but I'm curious
> just how they would handle selecting the spare register, if so.
> 
> Chapter 9 of the MSP430 Application Report Book discusses how to
> code PC-relative calls, this way:
> 
>       MOV PC, Rn        ; Address SC+2 > Rn
>       ADD #SUBR$, Rn   ; Add offset (SUBR  (SC+2))
>       CALL Rn           ; SC+2+SUBR(SC+2)) = SUBR
> 
> As you can see, this uses 4 words, 7 cycles, and scratches a
> register.
> 
> I believe there would have been nothing lost and everything
> gained if TI's designer(s) had backed off by one level of
> indirection in the case of the CALL instruction.
> 
> Jon
> 
> 
> .
> 
>  
> 
> ">http://docs.yahoo.com/info/terms/ 
> 
> 
> 


Reply by Noah Treuhaft September 17, 20032003-09-17
--- In msp430@msp4..., Jonathan Kirwan <jkirwan@e...> wrote:
> It takes 7 cycles, 4 instruction words, and a
spare register for
> computation in order to make a PC-relative function call.  It's
> possible that GNU assembler hides these details, but I'm curious
> just how they would handle selecting the spare register, if so.

You're quite right.  And the GNU assembler doesn't hide any details. 
I was just confused about the semantics of `call LABEL'.

Noah


Reply by Jonathan Kirwan September 16, 20032003-09-16
On Tue, 16 Sep 2003 17:59:37 -0000, Noah wrote:

>> >A good question - it's an
inconsistency in the syntax - if I had
>designed it,
>> >I would have made call the same as jmp, and used something like
>> >
>> >         call    @fptr
>> >
>> >for indirect function calls.
>> >...
>> 
>> IMHO, I think it's a mistake. This means you cannot have PC
relative
>calls. 
>
>I don't think that's true.  According to the Users' Guide
(SLAU049C),
>you can get a PC-relative call with `call LABEL'.  This works
>correctly with the GNU assembler; do other assemblers disallow it?

There isn't a single instruction on the MSP430 which yields a PC
relative call behavior.  I think it was a sad oversight on their
part (or Horst Diewald's part.)

It takes 7 cycles, 4 instruction words, and a spare register for
computation in order to make a PC-relative function call.  It's
possible that GNU assembler hides these details, but I'm curious
just how they would handle selecting the spare register, if so.

Chapter 9 of the MSP430 Application Report Book discusses how to
code PC-relative calls, this way:

      MOV PC, Rn        ; Address SC+2 > Rn
      ADD #SUBR$, Rn   ; Add offset (SUBR  (SC+2))
      CALL Rn           ; SC+2+SUBR(SC+2)) = SUBR

As you can see, this uses 4 words, 7 cycles, and scratches a
register.

I believe there would have been nothing lost and everything
gained if TI's designer(s) had backed off by one level of
indirection in the case of the CALL instruction.

Jon

Reply by Noah Treuhaft September 16, 20032003-09-16
> >A good question - it's an inconsistency in the syntax - if I
had
designed it,
> >I would have made call the same as jmp, and
used something like
> >
> >         call    @fptr
> >
> >for indirect function calls.
> >...
> 
> IMHO, I think it's a mistake. This means you cannot have PC relative
calls. 

I don't think that's true.  According to the Users' Guide
(SLAU049C),
you can get a PC-relative call with `call LABEL'.  This works
correctly with the GNU assembler; do other assemblers disallow it?

Noah



Reply by onestone September 16, 20032003-09-16
Bruce Cannon wrote:
> Thanks Al!
> 
> I still don't get two things:
> 
> 1. In you last comment about CALLing a label without '#', do you
mean that
> DO_THIS is then understood to be a label for a number which is an address
> to a memory location which in turn contains the address of the subroutine?
> 
> And also:
> 
> 2. Why do we need to write
> 
>     jmp    DoThis

In this case the JMP destination is an offset from the current PC, a 
single word operabd is used. Hence the net effect of the JMP instruction is
	MOV	DoThis(PC),PC

However that isn't strictly true, since the PC has been incremented, 
and, for compactness, DoThis is actually stored in the operand as a word 
offset, ie half the actual byte offset. Then the real effect is as follows:-

	MOV	DoThis(PC),PC+2

If you try and decode this from the operand you must calculate the 
follwing:-

	PC = PCold + 2 + OFFSEt * 2
	
Where the value OFFSET is stored in the last 12 bits of the operand.

> 
> but
> 
>     call   #DoThis

The CALL instruction here is using the absolute addressing mode, whereby 
The address of DoThis is stored in the operand. In fact CALL DoThis is 
also valid, but would be used for accessing a table of functions 
perhaps, when the address stored in the operand would be the contents of 
the address DoThis(PC+2)

SLAUE10B Appendix B page 19 shows all the different addresssing mode 
results for the CALL instruction.

There you go, all done, and no need to buy a book ;@}

Cheers

Al


Reply by Jonathan Kirwan September 15, 20032003-09-15
On Mon, 15 Sep 2003 16:49:43 -0700, Richard wrote:

><snip>
>Oh well, at least we are not fighting w/ the . (DOT) problem w/ BLISS!!!

Diss on BLISS?  The language in which much of VMS was written!
My friend and buddy language?  Why, I never!

Jon

Reply by Richard F. Man September 15, 20032003-09-15
At 09:27 AM 9/16/2003 +1000, Clyde Stubbs wrote:
>On Mon, Sep 15, 2003 at 11:39:10AM -0700, Bruce
Cannon wrote:
> > 1. In you last comment about CALLing a label without '#', do
you mean that
> > DO_THIS is then understood to be a label for a number which is an
address
>
>Basically this means you are wanting an indirect call via the referenced
>variable as opposed to calling the function at the specified address.
>
> > 2. Why do we need to write
> >     jmp    DoThis
> > but
> >     call   #DoThis
>
>A good question - it's an inconsistency in the syntax - if I had
designed it,
>I would have made call the same as jmp, and used something like
>
>         call    @fptr
>
>for indirect function calls.
>...

IMHO, I think it's a mistake. This means you cannot have PC relative calls.

Oh well, at least we are not fighting w/ the . (DOT) problem w/ BLISS!!!


// richard <http://www.imagecraft.com> 
<http://www.dragonsgate.net/mailman/listinfo>