EmbeddedRelated.com
Forums

mixing C and assembly

Started by Lax April 22, 2008
Walter Banks wrote:
> Stefan Reuther wrote: >>If you ask me, ISO/IEC 18037 is close to useless (at least, if it's the >>document which is also known as WG14 N1021). >>- the fractional types are nice, but inconsistent. Why should a >> 'short fract' have fewer bits than 'short int'? > > Because the short modifier isn't size specific. Use C99's size specific > data types
I wasn't criticizing that 'short fract' doesn't have a precise size. I was criticizing that its recommended size differs from that of 'short int'. Confusing IMHO. Of course, one could argue that a 'long double' has more bits than 'long int', so a precedent is set. But to me, 'fract' types are almost the same as 'int' types.
>>- named address spaces: wouldn't it be much more useful to define a >> general mechanism to place things in sections? This would also help >> Unix people. > > Named address space is for data memory processors data spaces > and ROM spaces. > Sections are one approach. ISO is responsible for documenting > standard practice.
Existing practice looks like this: __attribute__((section("foo"))), #pragma section "foo", section("foo"). I'd love to see something like that with a standard syntax. I think WG21 (C++) is discussing it. I would prefer such an approach over a fixed set of keywords because it allows solving several similar problems with similar syntax.
> My experience with 18037 has been that it has made coding small > embedded systems and DSP systems a lot easier.
My experience is that none of the compilers I looked at support it (ADI, GHS, GNU, MS, Microchip). Or they have hidden it well enough :-P
>>A question that comes up for me is: if I write 'SP = expression', can I >>use a complex expression? > > Yes. > >>What if the compiler decides it needs to spill >>some temporaries onto the stack? (and what if it does that only under >>specific circumstances, like a special set of runtime checks enabled? > > When you access the lowest levels of the processor there is > an assumption that the developer understands the consequences.
If you know how to think like a compiler, you can manage that. I'm a hobbyist compiler writer, so I know how a compiler thinks. Most of my colleagues don't. But even to me, estimating when a compiler will spill a variable to the stack is hard. But we all can read processor manuals and understand assembler.
>>But of course, I'll try to get into the >>high-level language as fast as possible. Actually, my current boot >>loader (final code size somewhere below 2k) even contains some C++ >>modules :-) But its tight main loop (decompression+decryption) would >>probably have been impossible to write in a compiled language. > > In earlier threads we showed a proof where any asm program > could be written in C in the same or less code space or execution time. > The specific white paper was for a very small 8 bit processor. > > http://www.bytecraft.com/C_versus_Assembly
They're writing assembler with C syntax, and showing are that their instruction chooser's patterns match the processor. Not too realistic if you ask me. In reality, one would declare variables normally (not by assigning them to fixed processor registers), and it would be an interesting C-vs.-asm test to see how the compiler assigns them to registers. At least, that's one reason why I use a compiler: it is much better at keeping track of register assignments over a dozen screenfuls of code than I. That aside, what does the compiler do when I use a register in my code, but the compiler needs it to evaluate an unrelated complex expression? Stefan
On Apr 25, 8:32=C2=A0am, David Brown <da...@westcontrol.removethisbit.com>
wrote:
> cbarn24...@aol.com wrote: > > On Apr 24, 1:44=EF=BF=BDpm, David Brown <da...@westcontrol.removethisbit=
.com>
> > wrote: > >> cbarn24...@aol.com wrote: > >>> On Apr 24, 12:43 am, David Brown > >>> <david.br...@hesbynett.removethisbit.no> wrote: > <snip> > >>>> Secondly, some processors have small fixed-size hardware stacks (smal=
l
> >>>> PIC's and AVR Tiny's are examples). =EF=BF=BDFor such devices, a sing=
le
> >>>> unnecessary "call" can waste a third of your stack resources.- Hide q=
uoted text -
> >>> Firstly you would be mad to try running C of these chips. Secondly you=
> >>> would not put call returns on the hardware stack unless you have some > >>> kind of death wish, you keep that space for the ISRs. > >> Firstly, you must then call me mad, along with all the customers for PI=
C
> >> C compilers targeted at the smallest > > > They teget them to get money from people like you. > > Are you trying to imply that I am the sort of person that will buy any > tool just because it says "C" on the box, and I think "C is always > better than assembler"?
I have no idea what kind of person you are. =C2=A0I am a believer in using the right tool for the
> right job, and I won't part with any money unless I see the tool giving > value for money. =C2=A0Thus for AVR Tiny work, I used avr-gcc - but I'd > recommend ImageCraft's AVR Tiny compiler for most users (avr-gcc is easy
Ive never used AVRs tiny or otherwise but I have used PICs extensively. I am convinced that C is pretty much useless on the small devices. If you or anyone else thinks different then post some code for a real project.
> to use for normal AVR's, but a bit more challenging for tiny's). =C2=A0I u=
sed
> C because it was the better choice for my development - if it were > inappropriate, I would have had no problem writing the code in assembly. > > Or are you implying that the companies behind these tools are selling > worthless tools to gullible punters? =C2=A0Walter Banks can answer for his=
> own ByteCraft tools, and I can tell you that ImageCraft wrote their AVR > Tiny C compiler because customers asked for it. =C2=A0Prices are very low =
-
> if you are doing significant work with AVR Tiny's, you'd have a hard > time justifying *not* buying it. > > > =C2=A0PICs, and ImageCraft's dedicated > >> AVR Tiny C compiler. =EF=BF=BDI've only used a Tiny once, but I wrote t=
hat
> >> program in C (using gcc - with a bit of arm-twisting to make it work > >> without RAM). =EF=BF=BDI studied the generated assembly - it is unlikel=
y that I
> >> could have improved on it more than a few percent if I had hand-write > >> the assembly. > > > I have yet to be convinced that any meaningful program can be written > > in C for these small devices. Maybe you could post yours. > > No, I can't post my code - it was a project for a paying customer.
Allways the same excuse, everyone seems to have a million dollars worth of code on PIC.
> > If you can write a meaningful program in assembly for a device, you can > also write a meaningful program in C (and in Forth, and Ada, and Pascal, > hand-compiled pseudocode, and any other language that can generate > object code with low overheads).
True but C doesn't have low overheads. =C2=A0The choice of language is a matter of
> what you find most suitable as a source language for writing the code. > > Perhaps you mean to say that you don't think there are C compilers that > can generate code for the AVR Tiny (or PICs, or whatever) with low > enough overhead that they can be sensibly used on such small micros. > The explanation for that is simply that you have not tried good modern > compilers.
Well can you get "try before buy" compilers? Can you get your money back if the compiler doesn't meet your expectations? I think we know the answer to both questions.
> > It is certainly the case that you can do more tricks with assembly than > in C, and you have a greater freedom in structuring your code. =C2=A0I've > written assembly code where the program code and data tables overlapped > at the edges to save space - you can't do that sort of thing in C. =C2=A0B=
ut
> unless you are willing to work particularly hard at it, a C compiler > will give you as tight code as you would write in assembly on such a micro=
. Not a chance, challenge me if you want, Walter did but changed his mind after I told him he couldn't have my assembly code untill after he'd done it in C.
> > > > >> Secondly, the AVR Tiny has no ram beyond its 32 cpu registers. =EF=BF=
=BDI find
> >> it hard to imagine that you could write a program that needed more than=
> >> 3 levels of calls (including interrupts) and have space in those > >> registers to make a software call stack. > > > Exactly! you cant. C is nested language, functions calling functions > > calling functions. Thats one reason why it isn't so good on these > > small chips. > > No, calling functions is *one* feature of C.
Wrong, thats the whole point of the language, programs within programs. Each block is isolated from the next, self contained, runs in its own space, memory allocated as needed at run time and released when finished with. Anything between braces is independant (or at least sould be). =C2=A0It is not the *only*
> feature of C (maybe you're thinking of Forth?).
I'm still waiting for Forth on a PIC. =C2=A0Certainly, most C
> programs are going to have a call tree of more than three levels - but > small programs will not necessarily need that many levels. > > You are also ignoring the difference between the abstract, source code > view and the generated object code. =C2=A0In the source code, you may defi=
ne
> separate functions and call them - the compiler may then inline them > when generating the object code and thus avoid the stack usage.
Indeed but then it used more limited code space instead. Worse still you make a small change to a product, you probably thought "this wont be hard", the compiler then changes its mind about inlining and it wont fit anymore, and you dont know why!!
> > > > > > > =EF=BF=BDThese are devices aimed at > >> small and simple programs - three levels of call stack is often suffici=
ent.- Hide quoted text -
> > >> - Show quoted text -- Hide quoted text - > > - Show quoted text -- Hide quoted text - > > - Show quoted text -
On Apr 25, 1:52=EF=BF=BDpm, Walter Banks <wal...@bytecraft.com> wrote:
> cbarn24...@aol.com wrote: > > > A layer of a stack on a PIC with only 8 levels (In one case 2 levels) > > > has a big impact the available subroutine return stack. > > > Hence the need to avoid C altogether. > > I think you confusing the limitations of the silicon with the > language tools you are using. Anything that can be written > in asm for a PIC I can write in C in the same space.
You can convert asm into primitive C and have your compiler change it back but where does that get you. What you cant do is write in C and get it as small as an asm program, at least not as easily as writing in asm in the first place.
> > w..
On Apr 25, 6:14=EF=BF=BDpm, Stefan Reuther <stefan.n...@arcor.de> wrote:
> Walter Banks wrote: > > Stefan Reuther wrote: > >>If you ask me, ISO/IEC 18037 is close to useless (at least, if it's the > >>document which is also known as WG14 N1021). > >>- the fractional types are nice, but inconsistent. Why should a > >> =EF=BF=BD'short fract' have fewer bits than 'short int'? > > > Because the short modifier isn't size specific. Use C99's size specific > > data types > > I wasn't criticizing that 'short fract' doesn't have a precise size. I > was criticizing that its recommended size differs from that of 'short > int'. Confusing IMHO. > > Of course, one could argue that a 'long double' has more bits than 'long > int', so a precedent is set. But to me, 'fract' types are almost the > same as 'int' types. > > >>- named address spaces: wouldn't it be much more useful to define a > >> =EF=BF=BDgeneral mechanism to place things in sections? This would also=
help
> >> =EF=BF=BDUnix people. > > > Named address space is for data memory processors data spaces > > and ROM spaces. > > Sections are one approach. ISO is responsible for documenting > > standard practice. > > Existing practice looks like this: __attribute__((section("foo"))), > #pragma section "foo", section("foo"). I'd love to see something like > that with a standard syntax. I think WG21 (C++) is discussing it. > > I would prefer such an approach over a fixed set of keywords because it > allows solving several similar problems with similar syntax. > > > My experience with 18037 has been that it has made coding small > > embedded systems and DSP systems a lot easier. > > My experience is that none of the compilers I looked at support it (ADI, > GHS, GNU, MS, Microchip). Or they have hidden it well enough :-P > > >>A question that comes up for me is: if I write 'SP =3D expression', can =
I
> >>use a complex expression? > > > Yes. > > >>What if the compiler decides it needs to spill > >>some temporaries onto the stack? (and what if it does that only under > >>specific circumstances, like a special set of runtime checks enabled? > > > When you access the lowest levels of the processor there is > > an assumption that the developer understands the consequences. > > If you know how to think like a compiler, you can manage that. I'm a > hobbyist compiler writer, so I know how a compiler thinks. Most of my > colleagues don't. But even to me, estimating when a compiler will spill > a variable to the stack is hard. > > But we all can read processor manuals and understand assembler. > > >>But of course, I'll try to get into the > >>high-level language as fast as possible. Actually, my current boot > >>loader (final code size somewhere below 2k) even contains some C++ > >>modules :-) But its tight main loop (decompression+decryption) would > >>probably have been impossible to write in a compiled language. > > > In earlier threads we showed a proof where any asm program > > could be written in C in the same or less code space or execution time. > > The specific white paper was for a very small 8 bit processor. > > >http://www.bytecraft.com/C_versus_Assembly > > They're writing assembler with C syntax, and showing are that their > instruction chooser's patterns match the processor. Not too realistic if > you ask me.
Your righter than right, thats exactly what he's doing.
> > In reality, one would declare variables normally (not by assigning them > to fixed processor registers), and it would be an interesting C-vs.-asm > test to see how the compiler assigns them to registers. At least, that's > one reason why I use a compiler: it is much better at keeping track of > register assignments over a dozen screenfuls of code than I. > > That aside, what does the compiler do when I use a register in my code, > but the compiler needs it to evaluate an unrelated complex expression? > > =EF=BF=BD Stefan

Stefan Reuther wrote:

> Walter Banks wrote: > > Stefan Reuther wrote: > >>If you ask me, ISO/IEC 18037 is close to useless (at least, if it's the > >>document which is also known as WG14 N1021). > >>- the fractional types are nice, but inconsistent. Why should a > >> 'short fract' have fewer bits than 'short int'? > > > > Because the short modifier isn't size specific. Use C99's size specific > > data types > > I wasn't criticizing that 'short fract' doesn't have a precise size. I > was criticizing that its recommended size differs from that of 'short > int'. Confusing IMHO. > > Of course, one could argue that a 'long double' has more bits than 'long > int', so a precedent is set. But to me, 'fract' types are almost the > same as 'int' types.
Actually the debate in WG14 started that way that their should be corresponding fract types to int types. There are several issues that needed to be addressed. The first was a signed fract had one less bit of significance than unsigned fract. Eventually the debate became focused on the relationship between accum and fracts and support for DSP applications and the data size of a default _Fract became the same as an int with provision for other fract types.
> > My experience with 18037 has been that it has made coding small > > embedded systems and DSP systems a lot easier. > > My experience is that none of the compilers I looked at support it (ADI, > GHS, GNU, MS, Microchip). Or they have hidden it well enough :-P
Most of my experience with 18037 is in compilers that support automotive engine controllers and cell phone DSP's. As we release updates for small embedded systems compilers 18037 support is part of what we ship.
> If you know how to think like a compiler, you can manage that. I'm a > hobbyist compiler writer, so I know how a compiler thinks. Most of my > colleagues don't. But even to me, estimating when a compiler will spill > a variable to the stack is hard. > > But we all can read processor manuals and understand assembler.
That is the reason that our listing files look as much like asm lists as possible. Embedded systems especially needs good system understanding
> > The specific white paper was for a very small 8 bit processor. > > > > http://www.bytecraft.com/C_versus_Assembly > > They're writing assembler with C syntax, and showing are that their > instruction chooser's patterns match the processor. Not too realistic if > you ask me.
It is not the kind of code anyone is likely to write. But it is a proof that anything written in asm can be written in the same space as C. It is also proof that the C compiler knows the whole ISA.
> In reality, one would declare variables normally (not by assigning them > to fixed processor registers), and it would be an interesting C-vs.-asm > test to see how the compiler assigns them to registers. At least, that's > one reason why I use a compiler: it is much better at keeping track of > register assignments over a dozen screenfuls of code than I.
Compilers are good at account operations, overlaying variables and register tracking for example.
> That aside, what does the compiler do when I use a register in my code, > but the compiler needs it to evaluate an unrelated complex expression?
Depends on the processor. Processors that have an ac and index, the registers are volatile and over written. Risc processors like the xgate and some of the engine controllers can have some global variables in registers. The compiler respects the application declarations. w..
In message 
<72b456ce-494f-43ac-8735-a8ea924caccf@26g2000hsk.googlegroups.com>, 
cbarn24050@aol.com writes
>On Apr 25, 8:32&#4294967295;am, David Brown <da...@westcontrol.removethisbit.com> >wrote: >> cbarn24...@aol.com wrote: >> > On Apr 24, 1:440 >> > wrote: >> >> cbarn24...@aol.com wrote: >> >>> On Apr 24, 12:43 am, David Brown >> >>> <david.br...@hesbynett.removethisbit.no> wrote: >> <snip> >> >>>> Secondly, some processors have small fixed-size hardware stacks (small >> >>>> PIC's and AVR Tiny's are examples). 0 >> >>>> unnecessary "call" can waste a third of your stack resources.- >> >>>>Hide quoted text - >> >>> Firstly you would be mad to try running C of these chips. Secondly you >> >>> would not put call returns on the hardware stack unless you have some >> >>> kind of death wish, you keep that space for the ISRs. >> >> Firstly, you must then call me mad, along with all the customers for PIC >> >> C compilers targeted at the smallest >> >> > They teget them to get money from people like you. >> >> Are you trying to imply that I am the sort of person that will buy any >> tool just because it says "C" on the box, and I think "C is always >> better than assembler"? > >I have no idea what kind of person you are.
Yet you said:-
>> > They teget them to get money from people like you.
You can't have it both ways.
>> No, I can't post my code - it was a project for a paying customer. > >Allways the same excuse, everyone seems to have a million dollars >worth of code on PIC.
Yes.. Or at least the cost of re-inventing it is far higher than continuing with the current code base.
>> If you can write a meaningful program in assembly for a device, you can >> also write a meaningful program in C (and in Forth, and Ada, and Pascal, >> hand-compiled pseudocode, and any other language that can generate >> object code with low overheads). > >True but C doesn't have low overheads.
Yes it does, very low in most cases. In fact I have seen comparisons where some C compilers produce faster smaller code than assembler. In some cases an experienced assembler programmer can produce, in the same time frame, an application that is smaller and faster than the C program but it is not common.
>Well can you get "try before buy" compilers? Can you get your money >back if the compiler doesn't meet your expectations? I think we know >the answer to both questions.
The answer is "yes" I don't know of any embedded C compilers you can't try before you buy. Some are size limited and others time limited. Some companies like IAR offer both size and time limited versions of some of their compilers.
>> It is certainly the case that you can do more tricks with assembly than >> in C, and you have a greater freedom in structuring your code. &#4294967295;I've >> written assembly code where the program code and data tables overlapped >> at the edges to save space - you can't do that sort of thing in C. &#4294967295;But >> unless you are willing to work particularly hard at it, a C compiler >> will give you as tight code as you would write in assembly on such a micro. > >Not a chance, challenge me if you want, Walter did but changed his >mind after I told him he couldn't have my assembly code untill after >he'd done it in C.
Well lets draw up a competition and agree the rules. You will probably need some one independent to hold the produced code until all have completed their solution.
>I'm still waiting for Forth on a PIC.
:-) -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Walter Banks wrote:
> Stefan Reuther wrote: >> Walter Banks wrote: >>>My experience with 18037 has been that it has made coding small >>>embedded systems and DSP systems a lot easier. >> >>My experience is that none of the compilers I looked at support it (ADI, >>GHS, GNU, MS, Microchip). Or they have hidden it well enough :-P > > Most of my experience with 18037 is in compilers that support > automotive engine controllers and cell phone DSP's.
A blackfin qualifies as either, doesn't it?
>>>The specific white paper was for a very small 8 bit processor. >>> >>>http://www.bytecraft.com/C_versus_Assembly >> >>They're writing assembler with C syntax, and showing are that their >>instruction chooser's patterns match the processor. Not too realistic if >>you ask me. > > It is not the kind of code anyone is likely to write. But it is a proof that > anything written in asm can be written in the same space as C. It is > also proof that the C compiler knows the whole ISA.
Sure, still I think it's a useless proof. One writes C because one doesn't want to know about the C<->asm correspondence. There are dozens of language-X-versus-language-Y comparisons, where a programmer fluent in X solves a problem in X and then ports it to Y, ignoring most of Y's idioms. As a result, X usually is faster. Such a comparison is bogus. A realistic comparison would be to let a programmer fluent in X solve the problem in X (for example, X="C"), and another one fluent in Y solve the problem in Y (for example, Y="asm"), and then compare the results. Assuming state-of-the-art compilers, I'd expect both to end up in the same region for most application tasks. (That aside, I would have expected a line like 'a - b;' to be completely optimised away instead of compiled into a 'cmp' or 'sub' insn.)
>>That aside, what does the compiler do when I use a register in my code, >>but the compiler needs it to evaluate an unrelated complex expression? > > Depends on the processor. Processors that have an ac and index, the > registers are volatile and over written. Risc processors like the xgate and > some of the engine controllers can have some global variables in registers. > The compiler respects the application declarations.
So if I place a variable in the accumulator, the compiler does not use it anymore for arithmetics? How does it compile 'b = c + d' on a machine that does arithmetics only on the accumulator (like a Z80)? Stefan

cbarn24050@aol.com wrote:

> On Apr 25, 1:52&#65533;pm, Walter Banks <wal...@bytecraft.com> wrote: > > cbarn24...@aol.com wrote: > > > > A layer of a stack on a PIC with only 8 levels (In one case 2 levels) > > > > has a big impact the available subroutine return stack. > > > > > Hence the need to avoid C altogether. > > > > I think you confusing the limitations of the silicon with the > > language tools you are using. Anything that can be written > > in asm for a PIC I can write in C in the same space. > > You can convert asm into primitive C and have your compiler change it > back but where does that get you.
It gets the accounting advantages of C. Variable reuse, register tracking, memory management and tracking.
> What you cant do is write in C and > get it as small as an asm program, at least not as easily as writing > in asm in the first place.
Having proven that any asm can be written in the same size (or less) in C then the focus becomes application implementation where the C compiler as an implementation aid that does well the two things that asm programmers don't do easily. 1) Accounting 2) With every change in an application algorithm start over and code again. Regards -- Walter Banks Byte Craft Limited Tel. (519) 888-6911 http://www.bytecraft.com walter@bytecraft.com
> Yes it does, very low in most cases. =EF=BF=BDIn fact I have seen comparis=
ons
> where some C compilers produce faster smaller code than assembler. =EF=BF=
=BDIn
> some cases an experienced assembler programmer can produce, in the same > time frame, an application that is smaller and faster than the C program > but it is not common.
Well I havent, post some, or if your worried about secrecy email it to me. Ive written several projects in both languages, the asm version has allways been much smaller.
> > >Well can you get "try before buy" compilers? Can you get your money > >back if the compiler doesn't meet your expectations? I think we know > >the answer to both questions.
> > The answer is "yes" I don't know of any embedded C compilers you can't > try before you buy. Some are size limited and others time limited. =EF=BF=
=BDSome
> companies like IAR offer both size and time limited versions of some of > their compilers.
Ive seen the code limited versions, not quite the full package are they. As for time limited, thats not really much help is it. Thats why they can afford to do it.
> > Well lets draw up a competition and agree the rules. You will probably > need some one independent to hold the produced code until all have > completed their solution.
Yes lets do that. Some small project on a small PIC so everyone can build and get working without spending too much money. Rules: Write your code, program device, verify it meets the project spec, post the memory map, and object file so everyone else can verify your program works.
> \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ > \/\/\/\/\ Chris Hills =EF=BF=BDStaffs =EF=BF=BDEngland =EF=BF=BD =EF=BF=BD=
/\/\/\/\/
> \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/- Hide quoted text - > > - Show quoted text -
> > You can convert asm into primitive C and have your compiler change it > > back but where does that get you. > > It gets the accounting advantages of C. Variable reuse, register > tracking, memory management and tracking.
Yes indeed but you havent written in C you've written in assember.
> > What you cant do is write in C and > > get it as small as an asm program, at least not as easily as writing > > in asm in the first place. > > Having proven that any asm can be written in the same size (or less) > in C
No you haven't!! then the focus becomes application implementation where the
> C compiler as an implementation aid that does well the two things > that asm programmers don't do easily. > > 1) Accounting
With only a few variables it's not that taxing.
> > 2) With every change in an application algorithm start over and > =EF=BF=BD =EF=BF=BD code again.
Rarely does that happen but Ive seen many a C function junked and started over.