EmbeddedRelated.com
Forums

Assembler Vs C-Compiler

Started by Tam July 10, 2003
Andreas Schwarz <andreas-s@andr...> wrote:

> Jonathan Kirwan <jkirwan@jkir...> wrote:
> 
> > When the exact-port was completed and tested, I then compared
> > the resulting memory footprints.  The original assembly code
> > occupied approximately 2k word of 14-bit instructions (it was on
> > the PIC16C73B.)  The final C code, after I stripped out the
> > forced inclusion of the darned unused FP library [geez was that
> > large], occupied almost 7k word of 16-bit instructions.
> 
> Ouch...
> 
> > Here's one to try, I've used before because it's a very
common
> > teaching algorithm, in generally portable and can use the
> > natural word size, and doesn't get into floating point
> > complications or even issues of signed comparisons.  Just your
> > basic algorithm with =, !=, <, +/- operation, and unsigned
> > integers.  It doesn't get much more basic and still be useful:
> > 
> > 
> >   unsigned int gcd (unsigned int a, unsigned int b)
> >   {
> >         if (a == 0 && b == 0)
> >             b= 1;
> >         else if (b == 0)
> >             b= a;
> >         else if (a != 0)
> >             while (a != b)
> >                 if (a < b)
> >                     b -= a;
> >                 else
> >                     a -= b;
> > 
> >     return b;
> >   }
> > 
> > 
> > Then compare the output with what you can come up with, doing
> > hand assembly.  Frankly, I'm curious about the MSP430 case,
> > where I honestly believe the C compiler has a darned good chance
> > to do almost as well as an assembly coder.
> 
> I tried it with MSPGCC:
> andreas@d700 tmp $ msp430-gcc -Os -g -c test.c -o test.o
> andreas@d700 tmp $ msp430-size test.o
>    text    data     bss     dec     hex filename
>      46       0       0      46      2e test.o
> andreas@d700 tmp $ msp430-objdump -d --source test.o > test.lst
> 
> The listing file is attached.

OK, here it is:


test.o:     file format elf32-msp430

Disassembly of section .text:

00000000 <gcd>:
  unsigned int gcd (unsigned int a, unsigned int b)
  {
        if (a == 0 && b == 0)
   0:	0f 93       	cmp	#0,	r15	;r3 As=
   2:	04 20       	jnz	$+10     	;abs 0xc
   4:	0e 93       	cmp	#0,	r14	;r3 As=
   6:	06 20       	jnz	$+14     	;abs 0x14
            b= 1;
   8:	1e 43       	mov	#1,	r14	;r3 As=
   a:	0f 3c       	jmp	$+32     	;abs 0x2a
        else if (b == 0)
   c:	0e 93       	cmp	#0,	r14	;r3 As=
   e:	02 20       	jnz	$+6      	;abs 0x14
            b= a;
  10:	0e 4f       	mov	r15,	r14	;
  12:	0b 3c       	jmp	$+24     	;abs 0x2a
        else if (a != 0)
  14:	0f 93       	cmp	#0,	r15	;r3 As=
  16:	09 24       	jz	$+20     	;abs 0x2a
            while (a != b)
  18:	0f 9e       	cmp	r14,	r15	;
  1a:	07 24       	jz	$+16     	;abs 0x2a
                if (a < b)
  1c:	0f 9e       	cmp	r14,	r15	;
  1e:	02 2c       	jc	$+6      	;abs 0x24
                    b -= a;
  20:	0e 8f       	sub	r15,	r14	;
  22:	01 3c       	jmp	$+4      	;abs 0x26
                else
                    a -= b;
  24:	0f 8e       	sub	r14,	r15	;
  26:	0f 9e       	cmp	r14,	r15	;
  28:	f9 23       	jnz	$-12     	;abs 0x1c

    return b;
  }
  2a:	0f 4e       	mov	r14,	r15	;
  2c:	30 41       	ret			
-- 
AVR-Tutorial, er 350 Links
Forum f AVRGCC und MSPGCC
-> http://www.mikrocontroller.net

Beginning Microcontrollers with the MSP430

Bruce, if you haven't noticed I can't even write neatly with a
word 
processor.

Al

Bruce Cannon wrote:
> I think it's somewhere in between, that 3rd pty support comes when
people
> see a potentially large new market developing, and this in turn helps
> accelerate the rolling ball; I don't think they wait till the market
is
> mature to write them, they will have likely been preempted by then.  I
> mentioned the PIC books here because I think they helped make it easy for
> lots of people to use those parts more quickly and productively, and I
> think even one book featuring the MSP430 would help a whole lot right now.
> 
> And it could focus on assembly programming ;)  maybe you could write it.
> 
> --Bruce
> 
> 
>>This is a little bit like the chicken and egg. personally I think the
>>books were written because the PIC was popular. No point expending lots
>>of effort, time and money on somethign that doesn't have a market
yet.
>>Just my thoughts from the ground floor, as one who was intimately
>>involved with Microchip in its transitional period from niche to
noticed.
>>
>>Al
>>
>>Bruce Cannon wrote:
>>
>>
>>>After low-cost tools I think the biggest influence driving the
>>>use of the PIC has to be the literally scores of tutorial books on
> 
> programming it
> 
>>>(mostly in assembly by the way).
>>>
>>>--Bruce
> 
> 
> 
> 
> .
> 
>  
> 
> ">http://docs.yahoo.com/info/terms/ 
> 
> 
> 


I think it's somewhere in between, that 3rd pty support comes when
people
see a potentially large new market developing, and this in turn helps
accelerate the rolling ball; I don't think they wait till the market is
mature to write them, they will have likely been preempted by then.  I
mentioned the PIC books here because I think they helped make it easy for
lots of people to use those parts more quickly and productively, and I
think even one book featuring the MSP430 would help a whole lot right now.

And it could focus on assembly programming ;)  maybe you could write it.

--Bruce

> This is a little bit like the chicken and egg.
personally I think the
> books were written because the PIC was popular. No point expending lots
> of effort, time and money on somethign that doesn't have a market yet.
> Just my thoughts from the ground floor, as one who was intimately
> involved with Microchip in its transitional period from niche to noticed.
>
> Al
>
> Bruce Cannon wrote:
>
> > After low-cost tools I think the biggest influence driving the
> > use of the PIC has to be the literally scores of tutorial books on
programming it
> > (mostly in assembly by the way).
> >
> > --Bruce


On Tue, 15 Jul 2003 13:21:10 +0100, Paul wrote:

>Well, CrossWorks produces something you'd
expect:

Thanks, Paul.  I'll be looking at these in more detail a little
later on, once I get a moment this evening to sit down and write
my own assembly version.

It's great that the compilers place the passed parameters into
registers.  I gather that this is quite normal, given the number
of excellent registers on the MSP430 (one of the reasons I
believed that the C compilers would do very well on this CPU --
the other being the available addressing modes.)

Quick questions.

Do all the compilers use the same associations on the MSP430?
Or do each of them make choices unique to themselves in some
way?  (Is there a collective standard in operation, in other
words?)

Are there compiler options which will change this particular
choice, evidenced by the assembly output posted?

Jon


On Tue, 15 Jul 2003 14:48:40 +0000, Andreas wrote:

>OK, here it is:

Thanks, Andreas.  I'll be looking at these in more detail a
little later on, once I get a moment this evening to sit down
and write my own assembly version.

Jon


Here's a quick and dirty attempt. I haven't checked it,other than
in my 
head. It takes 19 instructions vs 22 for Pauls compiler and 23 for GCC, 
a trivial gain, but a trivial function. Looking at it something says I 
should be able to squeeze it some more, but here's a start.

Al

GCD:
	CMP	R14,R15		;CHECK IF A = B
	JNE	L1		;IF NOT SKIP TO OTHER TESTS
	CMP	#0,R15		;WERE THEY BOTH = 0?
	JNZ	L2		;IF NOT RETURN B = A != 0
	INC	R15		;ELSE RETURN B = 1
L2:
	RET
L1:
	CMP	#0,R15		;TEST FOR A != 0 B = 0
	JEQ	L6		;AND IF SO RETURN B = A;
	CMP	#0,R14		;TEST FOR A = 0 B != 0 RETURN B = B
	JZ	L2
L3:
	CMP	R14,R15		;TEST IF R14 = R15 YET
	JC	L4		;IF B >= A THEN SUB A FROM B
	SUB	R15,R14		;ELSE R14 -= R15
	JMP	L5
L4:
	SUB	R14,R15		;R15 -= R14
L5:
	CMP	R14,R15
	JNZ	L3
L6:
	MOV	R14,R15
	RET

Jonathan Kirwan wrote:
> On Tue, 15 Jul 2003 13:21:10 +0100, Paul wrote:
> 
> 
>>Well, CrossWorks produces something you'd expect:
> 
> 
> Thanks, Paul.  I'll be looking at these in more detail a little
> later on, once I get a moment this evening to sit down and write
> my own assembly version.
> 
> It's great that the compilers place the passed parameters into
> registers.  I gather that this is quite normal, given the number
> of excellent registers on the MSP430 (one of the reasons I
> believed that the C compilers would do very well on this CPU --
> the other being the available addressing modes.)
> 
> Quick questions.
> 
> Do all the compilers use the same associations on the MSP430?
> Or do each of them make choices unique to themselves in some
> way?  (Is there a collective standard in operation, in other
> words?)
> 
> Are there compiler options which will change this particular
> choice, evidenced by the assembly output posted?
> 
> Jon
> 
> 
> 
> .
> 
>  
> 
> ">http://docs.yahoo.com/info/terms/ 
> 
> 
> 


Jon,

> Quick questions.
> 
> Do all the compilers use the same associations on the MSP430? 

Nope.  Not at all.

> Or do each of them make choices unique to
themselves in some 
> way?  (Is there a collective standard in operation, in other
> words?)

I think we all use slightly different calling conventions; I believe
ours happens to be the most useful, of course.  :-)

> Are there compiler options which will change this
particular 
> choice, evidenced by the assembly output posted?

Not to my knowledge.  The only thing that IAR will offer is to not use
R4/R5 for ROM monitor compatibility.  (Why would anybody now purchase
the monitor version of C-SPY, though?)

-- Paul.

At 10:31 AM 7/15/2003 -0700, Jonathan Kirwan wrote:
>On Tue, 15 Jul 2003 13:21:10 +0100, Paul wrote:
>
> >Well, CrossWorks produces something you'd expect:
>
>Thanks, Paul.  I'll be looking at these in more detail a little
>later on, once I get a moment this evening to sit down and write
>my own assembly version.

Heh, mind you, I haven't really thought about it, but from your posts, I 
was thinking that perhaps there are some special things, may be like you 
can take advantage of the comparison already done so you can skip some of 
the later steps :-)

The ImageCraft compiler produces the same code, except that for some 
reasons it decided it needs to move R14 (the parameter) to R4 first, so it 
needs couple more instructions to do so. Which means:
1) I need to figure out why it's doing that. It shouldn't and and
doesn't 
on ICCAVR, so I have forgotten to tune something in the register allocator 
(yes, we have a register allocator too. We don't use coloring. I wrote a 
coloring register 10 years ago, didn't like it much, so I am now reverting 
to the other viable alternative).
2) Even it needs to move it off R14, it is also doing unnecessary save and 
pop of R4. Unneeded since the function is a leaf function so it can trash 
anything it wants. Again, ICCAVR doesn't do that, so just more tuning. A 
good portion of the register allocator is common code between ICCAVR and 
ICC430, but obviously there are some tunings to be done.

>It's great that the compilers place the passed
parameters into
>registers.  I gather that this is quite normal, given the number
>of excellent registers on the MSP430 (one of the reasons I
>believed that the C compilers would do very well on this CPU --
>the other being the available addressing modes.)

The MSP430 is one of the best 8/16 bits micros from a code generator point 
of views. This is not referring to code size or anything, just ease of code 
generation.

>Quick questions.
>
>Do all the compilers use the same associations on the MSP430?

Probably not exactly. Since IAR comes first, we try to follow some of its 
register usage but may make different decisions on some stuff. I forgot 
offhand, I think IAR may even use different registers for param passing 
(R12/R13?) which is just sort of weird. Looks like Crossworks and us make 
"obvious" choice of using R14/15 for parameters.

>Or do each of them make choices unique to
themselves in some
>way?  (Is there a collective standard in operation, in other
>words?)

Hee hee :-) It would be nice. Some (bigger) systems define ABI (Application 
Binary Interface), this is where they may define things like this.

>Are there compiler options which will change this
particular
>choice, evidenced by the assembly output posted?
>
>Jon
>
>
>
>.
>
>
>
>">http://docs.yahoo.com/info/terms/

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


The Archelon/Quadravox AQ430 C compiler generates pretty much the same
code for the gcd example as the others do. Everybody passes the arguments
in registers. Since there are only two variables, both of which are
in registers, the translation into assembly code is simple, straightforward,
and seems to be pretty much the same as the posted equivalent hand code.

One of reasons why the msp430 is so attractive to C compiler vendors is
that the machine architecture is pretty close to being an ideal target for
the C language. It is a lot easier for a compiler to generate "hand code
quality" code for this machine than it is to generate code for something
like an 8051.


Here is the code generated by AQ430 C:

; Archelon URCC C 3.17 2003/07/03
; MSP430 CIF 2003/07/02
; Compiled "gcd.c" Tue Jul 15 17:43:58 2003
; 
;   unsigned int gcd (unsigned int a, unsigned int b)
        .pseg gcd_code
        .global _gcd
_gcd:
; ENTRY
; a at argloc 0 (0x0) in reg  size 2
; b at argloc 0 (0x0) in reg  size 2
;   {
;         if (a == 0 && b == 0)
        cmp     #0x0,r12
        jne     gcd_L1
        cmp     #0x0,r13
        jne     gcd_L1
;             b= 1;
        mov     #0x1,r13
        jmp     gcd_L2
gcd_L1:
;         else if (b == 0)
        cmp     #0x0,r13
        jne     gcd_L3
;             b= a;
        mov     r12,r13
        jmp     gcd_L4
gcd_L3:
;         else if (a != 0)
        cmp     #0x0,r12
        jeq     gcd_L5
;             while (a != b)
gcd_L6:
        cmp     r13,r12
        jeq     gcd_L7
;                 if (a < b)
        cmp     r13,r12
        jc      gcd_L8
;                     b -= a;
        sub     r12,r13
        jmp     gcd_L6
gcd_L8:
;                 else
;                     a -= b;
        sub     r13,r12
gcd_L9:
        jmp     gcd_L6
gcd_L7:
gcd_L5:
gcd_L4:
gcd_L2:
;     return b;
        mov     r13,r12
; EXIT
        ret     
;   }


All the best,

Preston Gurd
Archelon Inc.

On Tue, 15 Jul 2003 13:29:27 -0700, you wrote:

>At 10:31 AM 7/15/2003 -0700, Jonathan Kirwan wrote:
>>On Tue, 15 Jul 2003 13:21:10 +0100, Paul wrote:
>>
>> >Well, CrossWorks produces something you'd expect:
>>
>>Thanks, Paul.  I'll be looking at these in more detail a little
>>later on, once I get a moment this evening to sit down and write
>>my own assembly version.
>
>Heh, mind you, I haven't really thought about it, but from your posts,
I 
>was thinking that perhaps there are some special things, may be like you 
>can take advantage of the comparison already done so you can skip some of 
>the later steps :-)

I guess I'm not following, here.  What later steps?  What
comparison already done?  What special things?  Your thoughts
about me sound intriguing, but I just wish I'd been thinking
some of them so I could claim credit.  :)

>The ImageCraft compiler produces the same code,
except that for some 
>reasons it decided it needs to move R14 (the parameter) to R4 first, so it 
>needs couple more instructions to do so. Which means:

>1) I need to figure out why it's doing that.
It shouldn't and and doesn't 
>on ICCAVR, so I have forgotten to tune something in the register allocator 
>(yes, we have a register allocator too. We don't use coloring. I wrote
a 
>coloring register 10 years ago, didn't like it much, so I am now
reverting 
>to the other viable alternative).

Other alternative?  A simple register allocator that doesn't
look forward through a basic block, at all?  (Hmm.  Does anyone
do global [across blocks] register allocation?)

>2) Even it needs to move it off R14, it is also
doing unnecessary save and 
>pop of R4. Unneeded since the function is a leaf function so it can trash 
>anything it wants. Again, ICCAVR doesn't do that, so just more tuning.
A 
>good portion of the register allocator is common code between ICCAVR and 
>ICC430, but obviously there are some tunings to be done.

Yes, indeed.  Those aren't hard, so I'd expect that fix out very
soon!  hehe.

>>It's great that the compilers place the
passed parameters into
>>registers.  I gather that this is quite normal, given the number
>>of excellent registers on the MSP430 (one of the reasons I
>>believed that the C compilers would do very well on this CPU --
>>the other being the available addressing modes.)
>
>The MSP430 is one of the best 8/16 bits micros from a code generator point 
>of views. This is not referring to code size or anything, just ease of code 
>generation.

Tell me about it!  It's near a PDP-11 which was what was in mind
circa C's lead-up and eventual design.

>>Quick questions.
>>
>>Do all the compilers use the same associations on the MSP430?
>
>Probably not exactly. Since IAR comes first, we try to follow some of its 
>register usage but may make different decisions on some stuff. I forgot 
>offhand, I think IAR may even use different registers for param passing 
>(R12/R13?) which is just sort of weird. Looks like Crossworks and us make 
>"obvious" choice of using R14/15 for parameters.

Hehe.  I noticed this in the examples posted.

>>Or do each of them make choices unique to
themselves in some
>>way?  (Is there a collective standard in operation, in other
>>words?)
>
>Hee hee :-) It would be nice. Some (bigger) systems define ABI (Application 
>Binary Interface), this is where they may define things like this.

Well, other groups (as in the Mot 88k, for example) managed to
put out an ABI early in the game.

Thanks, Richard.  Wish you'd posted the assembly output, though.
;)

Jon