EmbeddedRelated.com
Forums
Memfault Beyond the Launch

mixing C and assembly

Started by Lax April 22, 2008
Walter Banks wrote:
> Stefan Reuther wrote: >>>register_sp SP; >>> >>>SP = int_value; >> >>What you're doing here is writing assembly with C syntax. It relies upon >>a heavily non-standard language extension, and makes assumptions about >>how the compiler behaves (you don't want the compiler to use the stack >>before your SP assignment, do you?). So instead of writing assembly in >>C, I prefer using the real thing. > > I actually agree with you it is very low level C. The purpose of ISO/IEC > 18037 was to define the low level syntax.
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'? - 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. - it still doesn't have a useful C-to-asm interface. The most useful interface I've seen so far is gcc's. Hence, what I've seen implemented so far all looks a little different. Fortunately, they implement gcc's asm extensions, at least partially :-)
> Most start up code is very processor > family specific. Writting start up code in C makes good use of C's > optimization like the branch/jump to main.
What optimization could be applicable to a piece of code which initializes few registers and then jumps to a label? A question that comes up for me is: if I write 'SP = expression', can I use a complex expression? 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? During my still short life, I've already seen quite some code that breaks even if you turn on optimisation, because suddenly the compiler notices that the delay loops actually don't do anything.) Hence if I want a specific assembler sequence in the program, I write it in assembler. Startup code is one such case. And, hey, those three instructions won't kill you. 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. Stefan

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
> - 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. Write a paper describing an alternative approach to named address space using sections and send it to WG14. (Contact me off line for contact details) ISO/IEC 18037 is a technical report not yet part of the C standards make a case for changes based on experience. My experience with 18037 has been that it has made coding small embedded systems and DSP systems a lot easier. Fixed point math provides data types with a focus on precision rather than dynamic range was missing from C. This addition makes many applications possible on very small processors.
> - it still doesn't have a useful C-to-asm interface. The most useful > interface I've seen so far is gcc's.
Get GCC to participate in the standards process. It would help everyone especially GCC
> Hence, what I've seen implemented so far all looks a little different. > Fortunately, they implement gcc's asm extensions, at least partially :-) > > > Most start up code is very processor > > family specific. Writting start up code in C makes good use of C's > > optimization like the branch/jump to main. > > What optimization could be applicable to a piece of code which > initializes few registers and then jumps to a label?
Jump paging. Why not let the compiler do the work.
> 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.
> During my still short life, I've already seen quite some code that > breaks even if you turn on optimisation, because suddenly the compiler > notices that the delay loops actually don't do anything.)
It varies from compiler to compiler.
> Hence if I want a specific assembler sequence in the program, I write it > in assembler. Startup code is one such case. And, hey, those three > instructions won't kill you.
I'm have never suggested that you shouldn't use asm it is an implementation choice. I am saying there is no compelling reason to use asm for startup code.
> 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 Regards, Walter..
"Walter Banks" <walter@bytecraft.com> wrote in message 
news:48108425.240346E6@bytecraft.com...
> cbarn24050@aol.com wrote: >> > What if the programmer puts (as he should) a return into main? >> > This means you have to stack an address for that return (possibly >> > the address of main). >> >> Indeed you do but it's not usually more than 2 bytes, you cant get >> much more optimal than that. > > 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.
Good point. On that sort of machine, you'd have to consider what you were going to use that stack for before you'd use up 1/8 (or even half) of your resources to handle that particular "it'll never happen" scenario. I usually work on systems with a lot more stack resource than that, so pushing a two or four byte return is using a very small percentage of that resource. A reasonable trade off in those environments. - Bill
Neil wrote:
> Walter Banks wrote: >> >> Neil wrote: >> >>> Walter Banks wrote: >>>> Vladimir Vassilevsky wrote: >>>> >>>>> You have to resort to assembly in the two special cases: >>>>> >>>>> 1. The system level work like switching the contexts of the tasks, C >>>>> startup code, etc. >>>>> >>>>> 2. The parts of code where the performance is very critical. >>>> In your second point I would qualify it to parts of code >>>> requiring exact timing on anything that we have released >>>> recently that seems to be the only limitation. >>>> >>>> >>> Do not forget the startup code >> >> Our startup code is in C. >> >> w.. >> >> >> > I am not sure how that works. I am talking about the code that jumps to > main after setting up the C environment.
So is he. There are small bits of the startup that must be in assembler (I use embedded assembly within the C code - Walter uses C extensions in his compilers that translate directly to matching assembly). But most of it can be written perfectly well in C. For example, code to copy the initialised data from flash to ram, and to zero the bss, can be written in C.
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: > >> cbarn24...@aol.com wrote: > >>> On Apr 23, 10:03 pm, David Brown > >>> <david.br...@hesbynett.removethisbit.no> wrote: > >>>> cbarn24...@aol.com wrote: > <snip> > >>>> Why would you bother optimising a traditional call to main into a jum=
p?
> >>>> =EF=BF=BD On some targets (in particular, several that Bytecraft targ=
et), the
> >>>> saved stack space is significant - and even the couple of saved flash=
> >>>> bytes is worth doing (given the negligible cost of the compiler's eff=
ort).
> >>> If it is on your project you are allready are allready up a certain > >>> creek without a paddle. In any event you wouldnt use a "traditional" > >>> ie a C type call to main from startup so stack saveing would be > >>> minimal. > >> First off, Walter writes compilers and their associated libraries - > >> saving a few bytes of stack space there means savings for all his users=
.
> >> =EF=BF=BD We are not talking about individual projects here. > > > No we're talking about startup code, do try to keep up. > > Walter writes compilers for a living, so his comments are based at least > partly on that - and I was commenting on your comments on his comments, > if you see what I mean. > > But we are also talking about project-specific startup code. > > When you are writing your own startup code, as is appropriate for some > projects, I can't really see why you would intentionally and knowingly > want to waste some ram, flash and run-time by specifically choosing a > call when a jump will do the job. =EF=BF=BDIf the source code is neater or=
> clearer, or faster to write, then that is obviously the decider. =EF=BF=BD=
But
> all other factors being equal, a jump will do the same thing. > > In fact, if you are using a compiler that does some sort of > whole-program optimisation, and you write your startup code in C, you > can expect that you will get neither a call to main, nor a jump to main > - the entire main() function will be inlined within the startup code. > > >> Secondly, some processors have small fixed-size hardware stacks (small > >> PIC's and AVR Tiny's are examples). =EF=BF=BDFor such devices, a single=
> >> unnecessary "call" can waste a third of your stack resources.- Hide quo=
ted 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. PICs, and ImageCraft's dedicated
> AVR Tiny C compiler. =EF=BF=BDI've only used a Tiny once, but I wrote that=
> 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 unlikely t=
hat 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.
> > 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. =EF=BF=BDThese are devices aimed at
> small and simple programs - three levels of call stack is often sufficient=
.- Hide quoted text -
> > - Show quoted text -
On Apr 24, 1:59=EF=BF=BDpm, Walter Banks <wal...@bytecraft.com> wrote:
> cbarn24...@aol.com wrote: > > > What if the programmer puts (as he should) a return into main? > > > This means you have to stack an address for that return (possibly > > > the address of main). > > > Indeed you do but it's not usually more than 2 bytes, you cant get > > much more optimal than that. > > 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.
> > w..
cbarn24050@aol.com wrote:
> On Apr 24, 1:44&#65533;pm, 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 (small >>>> PIC's and AVR Tiny's are examples). &#65533;For such devices, a single >>>> 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 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. Thus for AVR Tiny work, I used avr-gcc - but I'd recommend ImageCraft's AVR Tiny compiler for most users (avr-gcc is easy to use for normal AVR's, but a bit more challenging for tiny's). I used 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? Walter 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. Prices are very low - if you are doing significant work with AVR Tiny's, you'd have a hard time justifying *not* buying it.
> PICs, and ImageCraft's dedicated >> AVR Tiny C compiler. &#65533;I've only used a Tiny once, but I wrote that >> program in C (using gcc - with a bit of arm-twisting to make it work >> without RAM). &#65533;I studied the generated assembly - it is unlikely 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. 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). The 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. 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. 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. 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.
> >> Secondly, the AVR Tiny has no ram beyond its 32 cpu registers. &#65533;I 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. It is not the *only* feature of C (maybe you're thinking of Forth?). Certainly, 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. In the source code, you may define separate functions and call them - the compiler may then inline them when generating the object code and thus avoid the stack usage.
> > &#65533;These are devices aimed at >> small and simple programs - three levels of call stack is often sufficient.- Hide quoted text - >> >> - Show quoted text - >

cbarn24050@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. w..
In message <4811D3FC.421D6AD5@bytecraft.com>, Walter Banks 
<walter@bytecraft.com> writes
> > >cbarn24050@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 won't convince him. Some people just argue for the sake of it and have "religious" beliefs rather than engineering common sense. :-( It's like people arguing over 35mm film V DSLR or CD verses LP's. They are blinded by numbers and theoretical arguments etc. In reality C has been used on many safety critical systems. Errors that have caused multiple fatalities have been caused by assembler (FADEC). The Arianne 5 rocket crashed and that had flight controls written in Ada. It is not about the language. The other thing that really pisses me off is that all programmers who produce commercial tools are always assumed to be lying or not presenting the truth or in some way biassed in any discussion of tools. Yet programmers who are paid to produce software other than these tools are always totally honest. (And FOSS types always walk on water they are so saintly and have no bias whatsoever even if they do produce other commercial SW or systems) Walter has always been (AFAIKCS) completely honest and open (NDA's not withstanding) on this NG. The fact he has earned a good living writing tools he sells for longer than he cares to admit should point to his honesty. Unless all the people he sells his tools to are complete idiots or deluded? Given Walters involvement in the automotive industry and the amount of SW created with Bytecraft compilers that is in vehicles currently on the road we KNOW his tools are good. Otherwise you would have automotive SW failing all over the place. Of course as I distribute Bytecraft (for money) anything I say must be null and void I suppose? The argument that I distribute certain tools because in my professional opinion, as a developer for many years and some one who works with Walter on international standards, they are good reliable tools will not hold water with the nay -sayers because I can not be trusted because it is commercial..... :-) -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Walter Banks wrote:
> cbarn24050@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.
If you said "Anything you can write ..." I could tentatively agree. But not with "that can be". -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com **

Memfault Beyond the Launch