From: ralph@falcon.SLAC.Stanford.EDU (Ralph Becker-Szendy)
Newsgroups: alt.folklore.computers,comp.unix.misc
Subject: Re: The need for an assembler (was: Favorite CPU)
Date: 19 Aug 92 23:52:10 GMT
Followup-To: alt.folklore.computers
Organization: Stanford Linear Accelerator Center

In article <1992Aug19.160844.13884@auto-trol.com> davgot@auto-trol.com 
(David Gottner) writes (edited):
>I have complete control of the hardware with some HLL's (like C).  If I want
>a left shift I use '<<'.  If I want a signed multiply I use '*' on two signed
>numbers.  What more control could I want?
>
>I suppose that there are >>some<< limitations.  You can't write interrupt
>routines with standard C, but that is what assembler is for.  However, C
>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.
- When I want to test a particular bit in assembly language, I have
  several ways of doing it (in the Z80 for example I can rotate if it
  was the first or the last bit, I can mask and test, or I can do a bit
  test instruction). In some situations, some of these ways may be
  better than others. Example: I just read the status register from a
  device.  If I don't need the register any longer, I just mask the bit
  I want with an AND and check the result for zero/nonzero; this is the
  fastest method. If I care about the whole content, but need a quick
  look at the top or bottom bit, I rotate the registers so the desired
  bit walks into the carry flag and test that. Only if I really need the
  whole status register unmodified do I have to do a slow bit-test
  operation, or waste another register on saving/testing. How do you
  express these minute differences to your C compiler ?
- 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. If I even touch
  putc or printf I am deep in the mess of a horrible run-time-library,
  which is liable to be a lot less efficient.
- 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). I vaguely remember doing
  that for HOURS to get a tape reading program to work exactly right.
  How do you do this in C ?

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.

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.

-- 
Ralph Becker-Szendy                          RALPH@SLACVM.SLAC.STANFORD.EDU
Stanford Linear Accelerator Center                      RALPH@SLACVM.BITNET
M.S. 95, P.O. Box 4349, Stanford, CA 94309                    (415)926-2701
My opinion. This is not SLAC, Stanford U, or the US DoE speaking. Just me.