From: "D Poinsett"
Subject: Re: To C or not to C
Date: Sun, 5 Jan 2003 11:18:38 -0500
Organization: Posted via Supernews, http://www.supernews.com
References: <email@example.com> <firstname.lastname@example.org> <email@example.com> <firstname.lastname@example.org>
X-Newsreader: Microsoft Outlook Express 6.00.2800.1106
I misunderstood. I thought you were saying that there are operational
functions in the resulting code that could be done in assembler but not C
due to the semantic limitations of C.
I don't view this as "C or assembly language" issue. I think that for
projects of more than a few K, the embedded designer needs both a high level
language and assembly. I cringe at the thought of managing a large project
without a high level language. I prefer C because it lets me get pretty
close to the hardware and is relatively efficient for embedded designs. But
I would be in dire straights if I could not directly manipulate the
processor with inline assembly.
Your first example is about managing symbols and the project overall.
Judicious use of #defines, pre-compiled libraries (when justified for large
projects), and MAKE take care of this for me. If constants or fixed
references change so often that I need to recompile the entire project too
often, maybe these values SHOULD be variables.
Your second example is excellent. One could examine the assembly output from
the compiler to do this so it IS possible but counting instruction cycles
and making adjustments is far easier to do directly in assembler.
Couldn't your third example be done with pointers in C? Wouldn't it be even
more readable and easy to manage? Maybe I don't understand the example.
Jonathan, we had better be careful. This is sci.electronics.design. We are
going to get kicked off of here and sent to comp.arch.embedded!!
"Jonathan Kirwan" wrote in message
> On Sun, 5 Jan 2003 01:42:26 +0100, "Frank Bemelman"
> >"Jonathan Kirwan" schreef in bericht
> >> On Sun, 5 Jan 2003 01:35:19 +0100, "Frank Bemelman"
> >> wrote:
> >> >"Jonathan Kirwan" schreef in bericht
> >> >news:email@example.com...
> >> >
> >> >> I wasn't thinking about that. C can simulate "rotate left" and
> >> >> "rotate right," for example, or bit set and bit clear, as you
> >> >> mention. I'm talking about <> which simply cannot be
> >> >> reached. I'm not talking 'just clumsily', but *impossible* no
> >> >> matter how much or little code is written. Quite another story.
> >> >
> >> >Yes, but a rather short story. There isn't much desire to
> >> >manipulate stackpointers etc. in the middle of an (application)
> >> >program.
> >> Not what I'm thinking of. I'll provide a nice and *actual*
> >> example of one of my case histories which occured only a year
> >> ago for me, after some more guessing goes on. But it will be an
> >> "oh, yeah" after you see it.
> >Okay, I'll keep scratching my head in the meantime ;)
> Hehe, okay. I'll list a few which might trigger more. It's not
> even close to a complete list, but it does poke a few holes to
> suggest other ideas.
> Link-time constants. It's possible in most assembly languages
> to specify external symbols and assign a value to those symbols.
> Not the storage for them. The symbols themselves. COBOL
> compilers, using VALUE IS EXTERNAL for example, can reference
> these. C can, as well, with &symbol where 'symbol' is an
> extern. But if you want to create them, in C, you cannot.
> The advantage I've taken with them on larger projects is that I
> could avoid recompiling all the .C files which refer to, say, a
> #define symbol. Instead, I'd simply compile the configuration
> parameter .C file once and the symbol values would then be
> available in the .O or .OBJ file. The linker would then paste
> in the appropriate values at link time, based on these.
> For example, rather than:
> #define MAXBUF (128)
> in a .H file, I might instead use:
> const MAXBUF = 128;
> in a .C configuration file which I could then compile into an
> .OBJ or .O. The linker would have access to this symbolic value
> and would link it appropriately with any extern references to
> it, substituting the values at link time.
> Without this mechanism, the C compiler must recompile each and
> every .C file which includes the .H, rather than recompiling
> only the configuration constants file and then linking. For
> large projects, this can be kind of nice.
> But there are other values to this. For example, being able to
> specify absolute addresses for memory mapped peripheral
> registers and so on. Some of the embedded C compilers actually
> provide pre-compiled .OBJ or .O files which include these
> predefined symbolics in them for convenience and provide
> appropriate .H files for inclusion. But it isn't possible to
> produce those .OBJ files (or .LIB) without the assembler being
> involved. C just doesn't have a syntax to specify the semantics
> for it.
> Generating equal times in the 'then' and 'else' clauses of an
> 'if'. I recently encountered a situation, in doing bus
> arbitration between a variable number of asynchronous devices
> sharing it, where the timing of each address bit during the
> arbitration phase (much like the APIC bus on the Intel P II
> cpus) depended on some constant factors PLUS two times the
> variability in the bit timing. Since this was an active low,
> high impedance high type of line sharing, the microcontroller
> had to use two different mechanisms for driving a '0' and a '1'.
> This meant that I couldn't just mask the bit and drive it to the
> latch. I had to use an 'if' statement and do different things
> depending on whether the bit was a 0 or 1. However, if the
> 'then' and 'else' clauses had different timing, I'd have to
> double that variability and add it into the total bit time and
> this could greatly slow down the resolution process.
> C simply doesn't provide a syntax to allow the programmer to
> specify to the compiler that this is a desired outcome. Not
> even nice #pragma's for this, for example. No amount of
> screwing around with the C code would help here. It's plain and
> simple, not in the C card deck.
> Co-routines. It would take a while to properly elaborate this
> one. A quick example in pig-C might get the point across more
> quickly, though:
> for (p in Primes (1, 100))
> printint (p);
> for (n in Treewalk (t))
> printnode (n);
> In either of these cases, the function is called with the
> specified parameter list and doesn't quite "return" but instead
> "yields" a value back. The stack context for Primes() or
> Treewalk() must be maintained so that any local variables and
> the function parameters are maintained throughout the for loop.
> But when the function yields a value, the loop continues once,
> and then returns back from the yield. In effect, this is a
> coroutine -- cooperative, simple to implement, and powerful. In
> the case of the Primes() call, for example, the full set of
> primes do not need to be passed back nor fully computed before a
> yield takes place. There is no equivalent in C. But this is
> actually quite easy in assembly (and some other higher level
> Those are just three very real cases. There are also special
> uses of the ALU status bits which allow math and logical
> operations to be vastly more efficient, for some algorithms,
> than C. But now we are getting back onto the speed issue and
> I'm trying to point out that there are other issues. So I'll
> just note that detail.
> Assembly is quite a bit more flexible than C. The difficulty is
> that one needs to have a broader set of mental models in order
> to take advantage of that flexibility.
> There are also some more 'technical' differences, of course.
> Like interrupt procedures. C doesn't provide a syntax for this.
> Of course, many compiler vendors *do* provide extensions, so
> that it's not impossible for a C programmer -- such as a #pragma
> or a special keyword. So perhaps this is more a technicality.
> Or the ability to specifically place variables with initialized
> constant values in flash or rom. But many compilers now
> automatically detect this or provide some syntax to specify it.
> So perhaps another technicality here.
> Anyway, I just wanted to point out that those limiting their C
> vs assembly arguments to "speed" or "space", being unable to see
> any other reasons, are in fact myopic and color blind in their
> views. There is a bigger, more colorful world out there, most
> especially in embedded work. And C vs assembly for embedded use
> doesn't just boil down to speed and space and development time.
> I admit it often does so, but not always. And it's the times
> when it doesn't boil down that way, that things are really more