From: lasner@watsun.cc.columbia.edu (Charles Lasner)
Subject: Re: The need for an assembler (was: Favorite CPU)
Reply-To: lasner@watsun.cc.columbia.edu (Charles Lasner)
Organization: Columbia University
Date: Thu, 20 Aug 1992 23:30:59 GMT

In article <NEERI.92Aug20113346@iis.ethz.ch> neeri@iis.ethz.ch (Matthias Neeracher) writes:
>>>gives you so much control that assembly is rarely necessary.
>>
>>Nonsense. There are many (efficient!) things you can do in assembler
>>but not in C. And I'm sure even the best optimizing compilers don't
>>know all the tricks you can pull in assembler.
>>- If I call any subroutine or function in C, a large set of registers
>>  will be saved in some fashion, often unneccesarily.
>
>This is somewhat architecture dependent.

If this is architecture dependent, then C is too abstracted to express it.

>
>>- If there is a useful routine (like output a character) which is
>>  provided with a strange calling sequence (the character has to be in
>>  register X and a function code in register Y), I can not use it from
>>  within C, because there is no general way to express all possible
>>  calling conventions. No problem from within assembler.
>
>Not necessarily. Some compilers are quite good at being able to honor
>nonstandard calling sequences.

Not necessarily; there are *many* ways to call subroutines; totally
architecture dependant I admit, but I wouldn't rely on any all inclusive
statements here.

>
>>- If I need a really tight timing delay loop (say a microsecond), I
>>  just sit down with the CPU manual, count clock cycles, and do the
>>  correct number and type of instructions (pick the correct instructions
>>  to get the right number of clock cycles).
>
>Counting clock cycles isn't what it used to be. First of all, clock frequencies
>change about every year, so any program which is dependent on clock frequency
>is likely to be stuck with low end machines in a short time. Secondly, modern
>microprocessors with all of their caching mechanisms make getting an accurate
>timing this way quite difficult, not to say impossible.

On the 80x86 we do it all the time, and for any model.  It's based on a 
self-calibrating routine you wouldn't want to write in hll :-).
(for interested parties, it's in the MS-Kermit source distribution.)

>
>>So, C is not the answer to all questions. There are LOADS AND LOADS of
>>things which can not be expressed in C; and there are some thing which
>>any HLL compiler will do less efficiently than handcoded assembly.
>
>If I were trying to be nit-picking, I could object that for every program that
>is coded more efficiently in assembly, a compiler can be augmented to recognize
>the corresponding HLL program and generate the exact same assembly code.

This isn't possible; C and other languages are too abstracted from the
features of most machines.  They merely abstract a common subset which
hamstrings users of assembler.  This isn't an issue of language, it's the
one of accessing available elements of the machine, such as interrupt
handling, and solving of problems efficiently via co-routine, as well as
special-purpose algorithms which have limitations and restrictions placed
on their proper usage.  An abstracted language can't support features that
only work on subsets of a data type different for each particular situation.
The compiler loses knowledge of the context of the code in these cases, so
it has to resort to "safer" code that always works, albeit more inefficiently.

Moreover, there is far too much modeling of code generation based on a model
using a stack.  While it is true that occasionally a stack structure is needed,
it often isn't.  Perhaps statistically speaking most of the time, yet most
code is generated (ab)using a stack.  In some cases, the programmer's 
knowledgable of this can exert modest control of this slightly, as in the
PL/I feature that declares a function to be recursive or not.  But 
realistically, I don't see much effort on the part of hll programmers to
do much of this kind of optimization, certainly less than could be availed of,
and less than would be desirable.

This argument is mostly against C, not hll per se, since for example Fortran
generably requires no stack whatsoever.  (And expects the user to fake it
themselves for the few cases where it is needed, but that's perhaps a better
tradeoff than code that always uses a stack when it's only needed in the
few cases.)

>
>>Note: I am not advocating writing everything in assembler. That's
>>crazy. But good hand-coded assembler still has its place, in
>>particular in the tight spots of device drivers and realtime systems
>>(where every clock cycle counts). Therefore I agree that assembler is
>>RARELY neccessary.
>
>I agree with that paragraph.

It would seem that there are others that don't; they would insist that
hll programming is a panacea.

Also, the word necessary has to be defined carefully: it isn't necessary to
write better code than you can "get away with" only if you really can
get away with it.  Incrementally, this can add up to a "tainted" trade-off
depending on the application.  I fear that there is too much "up-front"
tilting of application specifications into hll directions.  Given all the
alternatives, some applications would get written somewhat differently.

A traditional method of writing large application is to write the main
program in Fortran.  Then let it call all of the functional modules, each
written as best as can be accomplished.  A "finished" product could be one
where all of the modules are 100% assembler, and the .1% of the Fortran
"glue" to stick it all together.

In any case, you agree with the statement that "assembler has some
necessary purposes in today's computers".

cjl
Newsgroups: alt.folklore.computers