[comp.misc] Assembly language

barmar@think.COM (Barry Margolin) (08/03/87)

In article <3664@well.UUCP> ewhac@well.UUCP (Leo (My glasses have gate arrays) Schwab) writes:
>	Expressing a new or complicated algorithm in a high-level language
>is a useful endeavor.  It allows you to clearly formulate and express the
>problem/procedure in machine-interpretable form.  However, once you have the
>basic algorithm down, your next step should logically be to translate that
>algorithm into assembly by hand.  Compilers can do a good job, but never as
>good as a human.

The point is not that humans can do a better job, but whether they
should bother.  The effort involved in converting a large program into
assembly code can be enormous.  A program that takes more than a
second to compile on a computer will probably take days or weeks for a
person to translate, plus more time to debug it again to make sure the
conversion was done right.  Is it worth it to get a tiny improvement
in the code?  It also takes a pretty good programmer to beat the
compiler; wouldn't his time be better spent designing or implementing
the NEXT program?

There are lots of things humans can do better than machines.  Some of
the best cars in the world are hand-built in small shops.  However, it
takes months for them to fill an order.  Detroit and Japan can
manufacture hundreds of cars on their assembly lines in the time these
shops can make one.  If you're rich, not in a hurry for a car, and
want something to show off, you can get a handmade one; if all you
care about is getting from here to there, the factory jobs will do
just as well.

Another consideration is that programs must be read and understood by
other programmers.  This is hard enough to do when the code is in a
high level language, but highly-tuned assembly is the hardest.
Remember, someone later on is going to have to fix a bug in or add a
feature to that code.

>	I point to accomplishments of the past.  SpaceWars fit in 4K of core
>on the PDP systems (as I understand it).  I have a copy of a very powerful
>music program for the 8080 that runs in 4K.  I have a copy of an 8080 BASIC
>interpreter that has multi-line user-defined functions, IF-THEN-ELSE,
>automatic structure indenting, error trapping, formatted I/O, and matrix
>functions.  It's 15K in size, and runs great in 32K.  Sonix is all assembly
>code, and its core is 29K in size (I think).
>
>	Meanwhile, MicroSlush is proud of the fact that the core of their
>AmigaBASIC interpreter runs in "only 80K" of RAM.  Truly pathetic.

Once upon a time memory was expensive and machines were slow, so it
was necessary to bum code in order to make the programs usable.

Great accomplishments of the past are easy to come by.  Columbus
discovered America using ships that used no fuel and created no
pollution.  The pioneers spread across this country using covered
wagons.  Now car manufacturers are proud when they can make a car that
gets 30 MPG and creates who knows how much carbon monoxide.  Is that
pathetic?  No, it's just different.

>	I'm not knocking high-level languages.  I use them a lot, and would
>be very lost without them.  In fact, if you know how a particular compiler
>behaves, you can get some very efficient code out of it.  But it should be
>agreed that assembly has its place in the world, and should not be
>arbitrarily poo-poohed.

And I'm not knocking assembly (it was my favorite when I was in high
school playing with PDP-8's and Z80's), but I think its time has
mostly passed, and it should be allowed a peaceful retirement.  Yes,
there are times when it should be called back to active duty, such as
when a highly-used routine needs to be super-optimized.  They say that
10% of the code is used 90% of the time; there should rarely be any
need to bum code in the other 90%.

The original poster was pointing out that some system REQUIRES certain
operations be done in assembler, presumably because no
high-level-language-callable library routine interfaces are provided
for them.  I don't know what machine was being discussed (I've only
seen the excerpts in the message I'm responding to), but I know that
the Macintosh is guilty of this in some places.  I think you would
agree that assembly should never be forced upon someone; if they want
to code or recode in assembly to conserve on computrons, fine, but it
should be the PROGRAMMER's choice.

>>Fear not, you're in good company. Donald E. Knuth (yes, that Knuth) is one
>>of the worst offenders. His "Art of computer programming" is almost useless
>>for day-to-day use because of "MIX".  [ ... ]
>
>	You didn't read his introduction to the book.  It's a cookbook of
>algorithms, with sample implementation in a hypothetical language.  It's up
>to you to translate the *algorithm*, not the code, over to what you want.  I
>suspect he invented a hypothetical language to force his readers to use the
>algorithms he presented, not just his code.  If he'd written it in Pascal or
>something, people would be tempted to drop the code into a machine
>unmodified, and they wouldn't learn anything.  Anyone can transliterate
>code, but can you use the *algorithm*?

I agree with the original poster, the programs (but not the
algorithms) in Knuth are useless.  I forgive him because a) the books
are about the best reference works available for the algorithms, and
b) they were written fifteen years ago (I think), when most systems
programmers still programmed in assembler.  I'm sure he would not
invent MIX if he were writing those books now.  If he wants to force
people to use the algorithms and not the code, he should simply LEAVE
OUT the code.  Before each program he describes the algorithm it
implements in detailed English.  If he really wants to include
programs, but doesn't want people to simply copy them, he could write
them in pseudocode or Ada(tm).  Also, none of his algorithms are very
large, so it doesn't take much effort to understand the programs.  I
think he was crazy to include the MIXAL assembler written in MIXAL in
the book -- do you really think anyone would bother to convert it?
Finally, if someone wanted to copy his code, it was pretty easy, as
MIX is similar to many machines of the day, so a mere transliteration
would not be difficult.

---
Barry Margolin
Thinking Machines Corp.

barmar@think.com
seismo!think!barmar

ken@rochester.arpa (Ken Yap) (08/04/87)

|The point is not that humans can do a better job, but whether they
|should bother.  The effort involved in converting a large program into
|assembly code can be enormous.  A program that takes more than a
|second to compile on a computer will probably take days or weeks for a
|person to translate, plus more time to debug it again to make sure the
|conversion was done right.  Is it worth it to get a tiny improvement
|in the code?  It also takes a pretty good programmer to beat the
|compiler; wouldn't his time be better spent designing or implementing
|the NEXT program?

Right on. In one of his Programming Pearls columns, Jon Bentley asks
the reader to estimate the cost in programmer wages of "improving" a
program by bit twiddling vs the cost of the CPU, etc, resources saved.

I suspect only heavily used programs like the kernel, compilers and
editors will pass this test. I know most of my programs wouldn't pass.

Of course, this is not to condone writing inefficient or unreadable
programs in the first place. In fact, one would save more (human)
resources later by writing clean programs.

	Ken

perkins@bnrmtv.UUCP (Henry Perkins) (08/04/87)

In article <1016@sol.ARPA>, ken@rochester.arpa (Ken Yap) writes:
> In one of his Programming Pearls columns, Jon Bentley asks
> the reader to estimate the cost in programmer wages of "improving" a
> program by bit twiddling vs the cost of the CPU, etc, resources saved.
> 
> I suspect only heavily used programs like the kernel, compilers and
> editors will pass this test. I know most of my programs wouldn't pass.

There's a class of programs that require assembly coding without
necessarily passing the Bentley test; that's when your software
goal is ambitious and your hardware choices are constrained.  The
constraint is generally marketing if the program is much cheaper
than the hardware it's to run on.

My example of this class of programs is Championship Golf, a game
I co-wrote.  I achieved real-time animation on a PCjr, which is
analogous to pushing a Cessna to Mach 1.  This tour de programming
wasn't worth the extra year of code tweaking and algorithm
rethinking it required; it would have been a better economic move
to require a faster processor to run the game on.  However,
marketing the program became MUCH easier if the program could be
advertised as running on any PC compatible with a color display,
rather than just on those with an 8 MHz 8088 or faster processor.
The less efficient program wouldn't have made it to market at all.
-- 
{hplabs,amdahl,3comvax}!bnrmtv!perkins        --Henry Perkins

It is better never to have been born.  But who among us has such luck?
One in a million, perhaps.

jeff@aiva.ed.ac.uk (Jeff Dalton) (08/07/87)

Another reason to avoid assembler is that instruction sets are
(rightly) becoming less user-friendly: it is expected that only
compilers (and compiler writers) will use them directly.

doug@edge.UUCP (Doug Pardee) (08/07/87)

About this assembly-language stuff...

Many say that they have no personal need for assembly language, and that
this shows that there is no need for assembly language.  I have no need for
a cement mixer truck.  If I ever need to haul some wet cement, I can put it
in a plastic bag in the trunk of my car.  Better yet, I'll haul a bag of dry
cement and mix it on the spot.  But does this prove that cement mixer trucks
are pointless?

Many say that assembly language is more difficult than C or Pascal, because
it doesn't look like those languages.  Clearly then, COBOL, BASIC, APL, LISP
and Prolog are also difficult, because they don't look like C or Pascal.

Many say a lot of other things about assembly, most of which aren't true.
Things like "takes too much code", and "hard to debug".  Those who are
saying these things will also tell you that they've never compromised their
virtue by having written in assembly themselves.

Folks, just because it looks *different* doesn't mean it's hard.  ANY
language looks hard to someone who doesn't know the language.  To an
assembly language programmer, C looks hard.  It's all in what you're
familiar with.

Assembly is just another language.  Like other languages, it has strong
points and it has weak points.  Its strong points are efficiency, both in
speed and in memory space, unlimited flexibility, and ease of debugging (yes,
EASE of debugging).  Its weakest point is non-portability.  It's also a bit
weak where a lot of subroutine calls have to be made using HLL interface
specs -- unless you have a good assembler program with nice macro facilities
you'll have to do a lot of messing around.

As a rule, assembly language programs are actually EASIER for another
programmer to pick up and figure out than are C programs (given that the
reader is fluent in the language).  This isn't because of anything inherent
in the language, but simply because assembly programmers usually comment
like fiends, while C programmers think their code is self-documenting.

In terms of the amount of code you have to write, assembly tends to be in
the middle ground.  More code than APL or C, less code than Pascal or COBOL.
However, the high level of commenting tends to increase the number of
characters well beyond the size of the usual (uncommented) Pascal program.

Well, actually, there is a bit of truth to the claims that assembly language
is hard to write in.  Unlike (say) BASIC, you can't program in assembly by
trial-and-error.  You have to know what you're doing or you aren't going to
get anywhere.  There are two consequences of this:   1) the inexperienced
assembly programmer has to learn an awful lot before he can start writing
programs that will run; and   2) programmers of marginal ability might
*never* be able to learn enough to get their assembly programs to run.

Assembly language programming isn't "impossibly hard", and it *is* still
widely used in the non-Unix world.  Regardless of what college professors
and Unix fans would have you believe.  There are a lot of applications out
there where portability is of no interest, but performance is critical.  For
those applications, assembly is clearly the language of choice.
-- 
Doug Pardee, Edge Computer Corp; ihnp4!mot!edge!doug, seismo!ism780c!edge!doug

ken@rochester.arpa (Ken Yap) (08/09/87)

|Folks, just because it looks *different* doesn't mean it's hard.  ANY
|language looks hard to someone who doesn't know the language.  To an
|assembly language programmer, C looks hard.  It's all in what you're
|familiar with.

Speaking from real experience with half a dozen assembler languages,
and not just micros, I found, as you say, that it wasn't any harder
than higher level languages once you get used to the notation. But that
catch is, you don't get as much accomplished for the same amount of
effort as you would with a HLL.

|Assembly is just another language.  Like other languages, it has strong
|points and it has weak points.  Its strong points are efficiency, both in
|speed and in memory space, unlimited flexibility, and ease of debugging (yes,
|EASE of debugging).  Its weakest point is non-portability.  It's also a bit
|weak where a lot of subroutine calls have to be made using HLL interface
|specs -- unless you have a good assembler program with nice macro facilities
|you'll have to do a lot of messing around.

You forgot another weak point - data structures. To set up a
structure/record in this PDP/11 macro assembler I used, I had to
generate the offsets with this non-intuitive syntax of equating symbols
with the relative addresses of fields. I don't want to do this kind of
niggly bookkeeping, that is what compilers are for.

|Assembly language programming isn't "impossibly hard", and it *is* still
|widely used in the non-Unix world.  Regardless of what college professors
|and Unix fans would have you believe.  There are a lot of applications out
|there where portability is of no interest, but performance is critical.  For
|those applications, assembly is clearly the language of choice.

Very often you can get the performance you want with a mixed language
approach - HLL for the non-critical portions, assembler for that
critical 5%.  But first I would check if there isn't a better
*algorithm* before fiddling with assembler code.

To the person who said that some applications like video games have to
fit into 256Kb of memory or whatever or it won't sell, I agree and
understand the constraints. The first Mac ROM was like that.  I'm just
glad I don't have to do that kind of shoehorning.

You're right, assembler sometimes gets bad press. It will be around as
long as Von Neumann architectures are with us, maybe even longer. Just
like every EE should know how to use a soldering iron, every computer
scientist should "dirty one's hands" at least once with assembler, if
only to get a better insight about how machines work at that level.

Assembler is just another option in a good programmer's bag of tools.
In an ideal world, one should choose and get the best tool for the
job.  In real world other reasons often decide the tools: "we have all
this code in FORTRAN already", "Pascal is nice but we can't afford to
buy a compiler", "yes, we would prefer C but none of the compilers are
reliable", "the DoD says we have to use Ada for this one".

Also don't forget there are even higher level languages like APL or
Icon.  I'm having fun writing this set partitioning program in Icon
right now.  No malloc'ing, no string length counting, no need to write
my own data abstraction routines. Compiles very quickly, executes
slower than C of course but it is fast enough. I may never bother to
recode the program in C after I get it working.

	Ken

rst@think.COM (Robert Thau) (08/09/87)

In article <892@edge.UUCP> doug@edge.UUCP (Doug Pardee) writes:
... an ode to assembly language, saying various things like:

>In terms of the amount of code you have to write, assembly tends to be in
>the middle ground.  More code than APL or C, less code than Pascal or COBOL.

Have you got data on this?  A fairly complicated one-line HLL
expression which involves, say, a few array references and a couple of
multiplications (which often have odd alignment rules) can easily
expand out to several *lines* of assembly language code, depending on
the addressing modes of the machine.  In particular, what gives you
the impression that PASCAL programs are that dramatically larger than C?

>...  Its strong points are ... and ease of debugging (yes,
>EASE of debugging).

In my experience, at least, the number of bugs is rougly linear in the
number of bytes of source code, for which see above.  Assembler also
suffers for the lack of type checking at either compile time or (as in
the case of LISP and SMALLTALK) run time, and the lack of direct
support for record structures.

You may be referring to the existence of ddt-type tools which allow
you to debug the program at the level of its (assembly language)
source, give or take the symbol table.  Source level debuggers for
HLLs are common these days, so assembler is at best on par.

Again, data would be helpful.

>As a rule, assembly language programs are actually EASIER for another
>programmer to pick up and figure out than are C programs (given that the
>reader is fluent in the language).  This isn't because of anything inherent
>in the language, but simply because assembly programmers usually comment
>like fiends, while C programmers think their code is self-documenting.

You are overgeneralizing mightily.  Both C and assembler portions
PDP-11 UNIX v6 source code, for example, were commented very sparsely.
Conversely, there are HLL programmers that "comment like fiends".
This is a question of style, not language.

>Assembly language programming isn't "impossibly hard", and it *is* still
>widely used in the non-Unix world.  Regardless of what college professors
>and Unix fans would have you believe.  There are a lot of applications out
>there where portability is of no interest, but performance is critical.  For
>those applications, assembly is clearly the language of choice.

A few boilerplate flames:

It is, by now, a truism that, in most applications, 10% of the code
takes 90% of the time.  Even with a lousy compiler, handcoding the
other 90% of your code buys nothing. 

Order-of-magnitude improvements in runtime often arise from changes in
algorithms.  In particular, you can often gain quite a lot by
incrementally modifying the state of a complicated data structure, the
manipulation of which would be quite difficult in assembler.

Lastly, modern optimizing compile technology is quite good.  After
looking at some of its output, I'd trust DEC's optimizing C compiler
("vcc" on ULTRIX) to come within 30% of my own handcoded assembler, in
both speed and size, and I've done quite a bit of assembly language (a
LISP interpreter for Z80 while I was in high school, more recently
a fair amount of Connection Machine assembler (PARIS)).

Personal opinion: In the light of all of this, it is hardly clear that
assembler is the language of choice *for an entire new program*, even
where portability is of no concern.  On the other hand, if you've got
tight requirements, good algorithms, and a lousy compiler, there
should be no hesitation in handcoding an inner loop.

>Doug Pardee, Edge Computer Corp; ihnp4!mot!edge!doug, seismo!ism780c!edge!doug

brad@looking.UUCP (Brad Templeton) (08/09/87)

Assembler is useful, and in spite of what people say, it sometimes is the
only way to do a job.

There is an attitude that computers will always get bigger and faster,
thus making them able to run compiled programs at the speed desired.
There is partial truth to this, but often it causes more problems for software.

Microsoft Basic would not be the #1 software product in history if it were
not written in assembler.

Lotus 1-2-3 would not be the top dollar software product in history if it
were not written in assembler.

Lotus Release 2 was still written in assembler.  Release 3 is planned to be
written in C, but that's still not out and it's going to be a lot bigger and
a lot slower than Release 2.

Compilers can optimize and sometimes produce better code for short stretches,
but the real problem with every compiler I have seen is in the function calling
and parameter passing.  Compilers must devise a general scheme, and they
all do it inefficiently.

Assembler is harder, because it's easier to make little bugs like forgetting
to pop a register.

What we need are assemblers that can do certain checks.  Things like balancing
the stack, understanding data flow and optional type checking.

We also need debuggers that can understand assembler programs in terms of
logical units, to make single stepping easier.  Yes, these are high level
language features, but they can be applied to assembler without losing a
smidgen of efficiency.

I program in HLLs most of the time.  But sometimes, to do the job the best
way you possibly can, you code in assembler.
-- 
Brad Templeton, Looking Glass Software Ltd. - Waterloo, Ontario 519/884-7473

cas@mtuxo.UUCP (C.STEVENS) (08/09/87)

Well, in my opinion (worth what it costs) a language is made complex
and hard to follow by the number of discrete statements it requires for
a task.  So a higher level language is easier to follow than assembler
because it takes fewer statements. 

The simplest (and least flexible) language would just have 1 statement!
You either did what the statement allowed or dropped back 10 yards and punted!
And that statement might compile to 10k of machine code!  But we trade
simplicity for flexibility.

And, assembler isn't any bigger that HLL, but it might be harder to debug
because it would take me 2-10 X (never measured difference) as much code 
to do the same tasks in HLL and assembler.  But the code is
2-10 X (never measured difference) smaller (per line)!

____________
The handsome guy in the wheelchair!

	(201)957-3902 -- Work		(201)671-7292 -- Home
	Cliff Stevens Jr.		Cliff Stevens Jr.
	rm. MT 1E228			1307 Knollwood Dr.
	AT&T -- End User Organization	Middletown NJ 07748
	Laurel Ave.			...!inuxc!mtuxo!cas
	Middletown NJ  07748		...!ihnp4!mtdcb!cas 

rcb@rti.UUCP (Random) (08/10/87)

In article <451@mtuxo.UUCP> cas@mtuxo.UUCP (C.STEVENS) writes:
>Well, in my opinion (worth what it costs) a language is made complex
>and hard to follow by the number of discrete statements it requires for
>a task.  So a higher level language is easier to follow than assembler
>because it takes fewer statements. 
>
>The simplest (and least flexible) language would just have 1 statement!

I've seen many 1 line APL programs that did significant work. I have never
seen one that was understandable without a lot of study.
-- 
					Randy Buckland
					Research Triangle Institute
					rcb@rti.rti.org [128.109.139.2]
					{decvax,ihnp4,seismo}!mcnc!rti-sel!rcb

gore@nucsrl.UUCP (Jacob Gore) (08/10/87)

/ nucsrl:comp.misc / brad@looking.UUCP (Brad Templeton) / 11:29 am  Aug  9, 1987 /
>Assembler is useful, and in spite of what people say, it sometimes is the
>only way to do a job.

Yes, but not in the examples used below.

>Microsoft Basic would not be the #1 software product in history if it were
>not written in assembler.
>
>Lotus 1-2-3 would not be the top dollar software product in history if it
>were not written in assembler.
>
>Lotus Release 2 was still written in assembler.  Release 3 is planned to be
>written in C, but that's still not out and it's going to be a lot bigger and
>a lot slower than Release 2.

All of these could have been easily implemented in an HLL, if it wasn't for
the fact that they had to have suitable performance on a machine/OS
combination that forced ad hoc limitations on the software.

Yes, sometimes it is beneficial to hand-code certain pieces of some software
in an assembly language for a machine.  When the running profile of the
software indicates which parts of the system need speeding up, then one goes
in to speed them up, and if that means recoding some of them in assembler, so
be it.  Coding the rest of the software in assembler is a waste of time.

Jacob Gore				gore@EECS.NWU.Edu
Northwestern Univ., EECS Dept.		{gargoyle,ihnp4,chinet}!nucsrl!gore

kurt@tc.fluke.COM (Kurt Guntheroth) (08/11/87)

In article <451@mtuxo.UUCP> cas@mtuxo.UUCP (C.STEVENS) writes:
>The simplest (and least flexible) language would just have 1 statement!

SNOBOL4 comes very close.  There is basically only one single statement form
that covers assignment, function invocation, declaration, and flow of
control.  Ugly, but it is indeed possible.

elg@killer.UUCP (Eric Green) (08/12/87)

in article <892@edge.UUCP>, doug@edge.UUCP (Doug Pardee) says:
> Assembly language programming isn't "impossibly hard", and it *is* still
> widely used in the non-Unix world.  Regardless of what college professors
> and Unix fans would have you believe.  There are a lot of applications out
> there where portability is of no interest, but performance is critical.  For
> those applications, assembly is clearly the language of choice.

Yawn. I think this is where we were 8 months ago, when I first subscribed to
comp.misc at my new news site.

Yes, I've written thousands of lines of assembly language code (my current
project is hovering at about 5,000), and yes, I equate programming in assembly
language, with a trip to the dentist, or breaking one's arm... painful. I
suppose if you're using a processor like the 6809 or the 68000 it wouldn't be
so bad, but it's hell on drain-bramaged processors like the 8080/z80, 6502, or
on any RISC processor (just for fun, try a Pyramid 90x on for size... you have
to look up each instruction you use, in order to see if it supports the
addresing mode you want to use...). As far as maintainability, etc. are
conerned, assembly language is definitely more maintainable than BASIC (at
least, traditional BASIC, none of this new-fangled multi-character names
bull), but anything else beats it hands down. Testing? Forget it. Run the code
in your head, play computer. Gets easier after awhile, till you can spot the
problem almost right off, but never as easy as in "C". As for SIZE... I
estimate that my 5,000 lines of carefully crafted 6502 assembly language,
could be implemented inmuch less than 1,000 lines of "C" (at an equivalent
commenting and readability level, of course -- no stacking the deck HERE!).

Conclusion: I have to use it, because on an 8-bit micro the only alternative
is FORTH (the DEFINITION of unreadability!), but that doesn't mean I have to
like it!
--
Eric Green   elg%usl.CSNET     Ollie North for President:
{cbosgd,ihnp4}!killer!elg      A man we can believe (in).
Snail Mail P.O. Box 92191      
Lafayette, LA 70509            BBS phone #: 318-984-3854  300/1200 baud

roy@phri.UUCP (Roy Smith) (08/12/87)

In article <892@edge.UUCP> doug@edge.UUCP (Doug Pardee) writes:
> As a rule, assembly language programs are actually EASIER for another
> programmer to pick up and figure out than are C programs (given that the
> reader is fluent in the language).  This isn't because of anything inherent
> in the language, but simply because assembly programmers usually comment
> like fiends, while C programmers think their code is self-documenting.

	My experience has been that most assembler code has one comment
per statement, often not very useful at that.  A typical example might be:

	add	r1, r2		; add r1 to r2, leave result in r2
	cmp	r2, r0		; is r2 greater than r0?
	bge	skip1		; if no....
	mov	r0, -(sp)	; push r0 onto the stack
	bra	skip2		; if yes...
skip1:	mov	r2, -(sp)	; push r2 onto the stack
skip2:	jsr	foo		; call subroutine foo

	Of course, this is not to say that there aren't assembler
programmers who comment the algorithm instead of translating the opcodes
into english, but they seem rare.  In fact, I would guess that in most
assembler courses (are there any of these anymore?) the above code would
get a positive nod from the instructor because every line had a comment,
just like it is supposed to.

	That's also not to say that that writing in a HLL automatically
make it easier to write useful comments.  I've seen lots of C code that I
couldn't figure out for the life of me with random incoherent comments that
don't do anything to help describe what's going on.  Ditto for Fortran,
Basic, Pascal, Lisp, etc.
-- 
Roy Smith, {allegra,cmcl2,philabs}!phri!roy
System Administrator, Public Health Research Institute
455 First Avenue, New York, NY 10016

peter@sugar.UUCP (Peter da Silva) (08/13/87)

All of you people flaming me (and flaming the people flaming the people
flaming me (and so on)) are totally missing the point. What I said was:

	"Don't express algorithms in assembly language."

What most people seem to have seen is:

	"Don't use assembly language."

That's (as many people have rightly pointed out) like saying "don't drive
pickup trucks because cars handle better". Sometimes you need a pickup.
Sometimes you need assembly. Mostly, however, all you get from the pickup
or the assembly language is a sense of glowing accomplishment at identifying
with the working class (in the case of the pickup) or the old-time hackers
who didn't have anything better (in the case of the assembler).

In any case da Silva's law #0x7FFE is still valid. When you are describing an
algorithm you should be concentrating on clarity rather than hack value. you
want to use the highest level code available. Unless the algorithm you're
trying to explain is Forth's inner interpreter... then use PDP-11 assembly.
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter (I said, NO PHOTOS!)

doug@edge.UUCP (Doug Pardee) (08/14/87)

[Note to the reader:  I'm trying hard to avoid any "'Tis not! -- 'Tis so!"
arguments, and instead to concentrate on expanding my explanations -- DLP]

>A fairly complicated one-line HLL
>expression which involves, say, a few array references and a couple of
>multiplications (which often have odd alignment rules) can easily
>expand out to several *lines* of assembly language code, depending on
>the addressing modes of the machine.

True.  But this is cherry-picking for the example which best illustrates
your point.  Counter-example: this line of 80x86 assembler expands into 
several lines of just about any HLL:
  REP MOVSB

When you count HLL lines, don't forget all of those lines that don't even
generate any code at all.  How about the ever-popular C line, "}"?

That is petty stuff, though.  The real point is that some applications
are "naturals" for the HLL, in which case I say DO use the HLL.  But for
many others you have to go out of your way to accomplish the task, and
that usually means extra HLL code.

>Assembler also suffers ... the lack of direct support for record structures

Another netter mentioned this too.  This is not a fault of assembly
language, this is a deficiency in the assembler software package you're
using.  These record structures (often called DSECTS in assembly) are
available with IBM 360/370 assemblers, and with the Microsoft assembler for
the IBM PC.  No doubt with other assemblers too.

Unfortunately, in the Unix universe it is assumed that nobody programs in
assembler, so Unix assemblers tend to be unusable trash.  A vicious cycle.

>It is, by now, a truism that, in most applications, 10% of the code
>takes 90% of the time.
> ...
>Order-of-magnitude improvements in runtime often arise from changes in
>algorithms.

Granted.  No arguments from me.

But (and I bet you just *knew* there was going to be a "but"...)

Once you've selected the best algorithm you can find (if you look for it),
and once you've optimized the slow 10% of your code so that you no longer
have any "hot" spots (if you bother), the program still could go a number of
times faster if it was coded in assembler.  [How many times faster?  Depends
on how poorly the application fit the HLL in the first place.]

I'm trying to make two distinct points here:  1) one of the biggest reasons
that HLLs are used for applications that should have been done in assembly
is programmer laziness.  A lazy programmer probably won't look for the best
algorithm, and certainly won't bother to locate the hot spots and fix them.
A programmer who cares enough to use the right algorithm, and who cares
enough to find and fix the hot spots in his program, is usually a programmer
who cares enough to use the right language for the job, even if it happens
to be (horror of horrors) assembly language.

2) the "magic" that results from selecting the best algorithm, and of
finding and fixing hot spots, is *not* confined to HLLs.  It works just as
well for assembly language.

>("vcc" on ULTRIX) to come within 30% of my own handcoded assembler,

I've gotta repeat myself: if the application is a "natural" for C or some
other HLL, then USE that HLL.

It's really not fair to compare compiler output versus handcoded assembler
for those applications.  A proper comparison is to select an application
which *should* be written in assembler, and compare that assembly code
against the compiler output for the kludge you had to write in the HLL.

By the way, in many non-Unix applications you'd *kill* for "only" a 30%
improvement in code size and/or speed.
-- 
Doug Pardee, Edge Computer Corp; ihnp4!mot!edge!doug, seismo!ism780c!edge!doug

doug@edge.UUCP (Doug Pardee) (08/14/87)

>Personal opinion: In the light of all of this, it is hardly clear that
>assembler is the language of choice *for an entire new program*, even
>where portability is of no concern.

In the Unix world, you can probably sell this idea.  In the non-Unix world,
little details keep getting in the way.  Details like the biggest micro-
controllers available (such as the 68HC11A8) only have 8K of ROM, and they
cost tons more than the more common 2K chips like the 8049.  And if the
company's gonna sell a few million of whatever the chips are going in,
programming it in assembly language will save tens of millions of dollars.

Details like there are a lot of IBM PC assembly programmers, so that if you
try to introduce a PC software package written in HLL, your competitors will
laugh all the way to the bank.  Ask the folks at Context/MBA how it feels
to be first-to-market via HLL coding, and then just as sales start popping
to get wiped off the software map by some speedy johnny-come-lately with a
stupid name like 1-2-3.  Oh sorry, can't ask 'em; they're out of business.

Details like how people and companies outside of the Unix world don't give
a hoot about keeping up with the "latest technology", they want to get the
cheapest computer they can that will do the job, and then hang on to it as
long as possible before going through the expense and hassle of replacing it.
And they'll only buy software that fits into their machine and runs quickly.

Details like projects that require a lot of performance out of low-bidder
hardware.  Such as a (genuine) flight simulator I worked on -- our visual
system drove 14 1000x1000 pixel displays, with images updated 30 times a
second.  The computers: 3 SEL 32/75s, equivalent to maybe large PDP-11s.

Details like projects that flat out push the state of the art for systems in
a given price range.  Projects which you can either do now in assembly or
wait 5 years for more powerful systems to show up in that price range.  The
Microsoft Flight Simulator could probably be done in C on the new Compaq 386
with only a couple of meg of memory.  5 years ago it was done on a 256K PC.

Computers and programming might be treated as some big game in Unixland, but
elsewhere it's serious business (as in $$$ business).  Assembly coding gives
the most "bang for the hardware buck", as the MBAs say.  The question then
becomes one of trading off those saved hardware bucks against software bucks
(higher paid programmers plus heavy cost if porting is ever needed).

In that tradeoff, HLLs generally win for "just for us" applications as long
as it looks like the program won't strain the limits of the current hardware
system.  Also where transportable code is critical.  But that still leaves a
*lot* of programs for which assembly is the lowest cost language.
-- 
Doug Pardee, Edge Computer Corp; ihnp4!mot!edge!doug, seismo!ism780c!edge!doug

cas@mtuxo.UUCP (C.STEVENS) (08/14/87)

In article <1326@killer.UUCP>, elg@killer.UUCP (Eric Green) writes:
# As for SIZE... I
# estimate that my 5,000 lines of carefully crafted 6502 assembly language,
# could be implemented inmuch less than 1,000 lines of "C" (at an equivalent
# commenting and readability level, of course -- no stacking the deck HERE!).

But how do the compiled/assembled object files compare in size?  I betcha the
assembly lang. file is a bit smaller, but not usually worth the trouble, in my
opinion!

____________
The handsome guy in the wheelchair!

	(201)957-3902 -- Work		(201)671-7292 -- Home
	Cliff Stevens Jr.		Cliff Stevens Jr.
	rm. MT 1E228			1307 Knollwood Dr.
	AT&T -- End User Organization	Middletown NJ 07748
	Laurel Ave.			...!inuxc!mtuxo!cas
	Middletown NJ  07748		...!ihnp4!mtdcb!cas 

cas@mtuxo.UUCP (C.STEVENS) (08/14/87)

In article <2840@phri.UUCP>, roy@phri.UUCP writes:
# 	add	r1, r2		; add r1 to r2, leave result in r2
# 	cmp	r2, r0		; is r2 greater than r0?
# 	bge	skip1		; if no....
# 	mov	r0, -(sp)	; push r0 onto the stack
# 	bra	skip2		; if yes...
# skip1:	mov	r2, -(sp)	; push r2 onto the stack
# skip2:	jsr	foo		; call subroutine foo

Wish I commented like that!:-)
____________
The handsome guy in the wheelchair!

	(201)957-3902 -- Work		(201)671-7292 -- Home
	Cliff Stevens Jr.		Cliff Stevens Jr.
	rm. MT 1E228			1307 Knollwood Dr.
	AT&T -- End User Organization	Middletown NJ 07748
	Laurel Ave.			...!inuxc!mtuxo!cas
	Middletown NJ  07748		...!ihnp4!mtdcb!cas 

bobmon@iucs.UUCP (08/15/87)

In article <2840@phri.UUCP> roy@phri.UUCP (Roy Smith) writes:
>
>	My experience has been that most assembler code has one comment
>per statement, often not very useful at that.  A typical example might be:
>
>	add	r1, r2		; add r1 to r2, leave result in r2
>	cmp	r2, r0		; is r2 greater than r0?
>	bge	skip1		; if no....
>	mov	r0, -(sp)	; push r0 onto the stack
>	bra	skip2		; if yes...
>skip1:	mov	r2, -(sp)	; push r2 onto the stack
>skip2:	jsr	foo		; call subroutine foo
>
>	Of course, this is not to say that there aren't assembler
>programmers who comment the algorithm instead of translating the opcodes
>into english, but they seem rare.  In fact, I would guess that in most
>assembler courses (are there any of these anymore?) the above code would
>get a positive nod from the instructor because every line had a comment,
>just like it is supposed to.

Sorry, I hafta defend my honor here.  I'm a grad student, I just (today!)
finished teaching an undergraduate assembly-language course.  Actually it's
called "Computer Structures", but it's centered on the machine language.

I've gone to the point of public ridicule to discourage the "add memory to
register" style of comments.  I specifically said that I preferred a block
of comments about a subroutine to line-by-line comments.  I told them that
the comments should tell me WHY, not WHAT.  I told them to write the kind of
comments they would want to read if they had to debug their own code in
6 months.

Yes, it works.  At least, for some of them.  I give grades to distinguish
between those who pick up good techniques and those who don't.  Wanna see
some well-commented assembly code?  Wanna hire one of my brighter kids?
(They even use metric units...)

robertd@ncoast.UUCP (08/15/87)

    Well, this is my opinion. Assembler is easy in concept but difficult in
reality. 

    I did a little programming in 8085 (Yes, 8085) and all I had to remember
were less then 255 op-codes. This may seem alot but the more you use it the
more you remember. The concept is also easy to understand if you like to
picture the innerds of your computer. The commands are simple  -  not complex
at all.

    However, logicly speaking, an assembler program is difficult to follow and
grasp. You would HAVE to "comment fiendishly" so the person can see what it is
doing. Logicly on the human mind , a statement like this:

    IF A = 8 THEN GOTO 5000

is a little easier to follow then this:

    CPI 8H
    JZ 0C00H

    BASICly speaking, assembler is easier in concept, but more difficuly to
read debug and follow.

    If readability on a program is GREATLY important, and efficientcy is not,
assembler isn't a good idea.

		[> Rd
-- 
North Coast Computer Resources(ncoast) - 216-781-6201 (or 781-6202)

UUCP:decvax!cwruecmp!ncoast!robertd

Sysop: NEODG (login "sbbs")

len@array.UUCP (Leonard Vanek) (08/17/87)

I could not resist pointing this comment out to the readers of comp.lang.ada.
It seems that the (lack of) credibility of Ada(tm) is simply taken for
granted in some circles.

In article <7197@think.UUCP> barmar@godot.think.com.UUCP (Barry Margolin) writes:

>I agree with the original poster, the programs (but not the
>algorithms) in Knuth are useless.
          ...
>									If he really wants to include
>programs, but doesn't want people to simply copy them, he could write
>them in pseudocode or Ada(tm).


Len Vanek
{utzoo mnetor}!dciem!array!len
Array Systems Computing
Toronto

wcs@ho95e.UUCP (08/18/87)

In article <7197@think.UUCP> barmar@godot.think.com.UUCP (Barry Margolin) writes:
:In article <3664@well.UUCP> ewhac@well.UUCP (Leo (My glasses have gate arrays) Schwab) writes:
:>	Expressing a new or complicated algorithm in a high-level language
:>is a useful endeavor.  It allows you to clearly formulate and express the
:>problem/procedure in machine-interpretable form.  However, once you have the
:>basic algorithm down, your next step should logically be to translate that
:>algorithm into assembly by hand.  Compilers can do a good job, but never as
:>good as a human.
	It's nice to find an assembler advocate who's rational.  (I may
	flame Doug Pardee later on :-)).  But no, once you've expressed
	the algorithm in a HLL, your next step is to put together the
	entire set of programs or tools to solve your problem, and test
	the heck out of them.  Even with good algorithm design, it's
	not usually obvious how the program will really be *USED* once
	it works.  Programming in a HLL gives you three main things:
		- Problem Formulation in a problem-oriented language
			that a machine can execute.
		- A prototype so you can debug the formulation - SOON.
		- The ability to change the program RAPIDLY.

	You'll always throw the zeroth version away.  You should usually
	throw the next version away (though Marketing may drag it out
	of the trash and sell it as Release 1.)  So it doesn't matter
	that it's three times as big and twice as slow as if you did it
	in assembler, because you'll have a much better product when
	you finally do the production version.  If the performance is
	adequate (it often is!), then market it.  If you work for a
	large company, distribute it widely internally.

	You'll do a lot better by getting the features right than making
	it twice as  fast - witness Microslow Windows.  If you work well
	with  your  customers,  they'll  come back  with  all  kinds  of
	suggestions about  how they use it  and what they want  added or
	improved, and many of them aren't the ones you tuned it for.
	Ignore most of them, put the good ones into your product and
	get Release 2 out fast enough to satisfy people.

	(To give Doug a little slack, if the problem you're trying to
	solve is to make hardware behave, then a machine language may
	be more problem-oriented than C or Fortrash.  But for most
	people, and most problems, that's not true.  Even with the
	Macintosh, much of the "really fine-tuned" was outdone by
	compilers, once good compilers became available.  I agree that
	assembler is useful until you get a decent compiler.)

	But wouldn't it have made more sense to do a mediocre compiler,
	and use it for the ROM?  It *would* have been twice as big and
	not as fast, but it would be *much* more accessible to
	programmers.  More people would have developed good Macintosh
	software, and maybe there'd be more Macs around instead of these
	braindamaged MS-DOS machines.

 -----------
	I suppose all this says I should do most of my programming in a
	high-level language like ZetaLisp instead of C and Shell.
-- 
#				Thanks;
# Bill Stewart, AT&T Bell Labs 2G218, Holmdel NJ 1-201-949-0705 ihnp4!ho95c!wcs

ken@argus.UUCP (08/18/87)

In article <2840@phri.UUCP>, roy@phri.UUCP (Roy Smith) writes:
> 	My experience has been that most assembler code has one comment
> per statement, often not very useful at that.  A typical example might be:
[example removed]
> 	Of course, this is not to say that there aren't assembler
> programmers who comment the algorithm instead of translating the opcodes
> into english, but they seem rare.  In fact, I would guess that in most
> assembler courses (are there any of these anymore?) the above code would
> get a positive nod from the instructor because every line had a comment,
> just like it is supposed to.

One instructor at this school was infamous for his insistence that every
line of assembler must have a comment on it.  My preference was to put
what the routine did in a block at the beginning, and then note the
functions of the branch statements only.  After I got points taken off
for not putting 'proper' docomentation in I wrote a program that
checked each line for a comment.  If there was one the line was ignored,
otherwise a comment would be generated from the assembler code.  For
example, if the op code was 'LR R1,R2' the comment generated would be
'* load register R1 with R2'.  Yes I know that this comment is useless,
but when the principal grading criteria is how well I follow the
instructors inane documentation rules rather than the correctness of the
program and/or the usefulness of the comments, I ran this program to
generate the comments.

> 	That's also not to say that that writing in a HLL automatically
> make it easier to write useful comments.  I've seen lots of C code that I
> couldn't figure out for the life of me with random incoherent comments that
> don't do anything to help describe what's going on.  Ditto for Fortran,
> Basic, Pascal, Lisp, etc.

One thing that has bugged me about a lot of programs I've seen is that
people seem to abor using variable names that go with the function of
the variable.  Sometimes they will comment at the declaration, but it
would be far better if they chose names that made sense.  An example
follows:

i     -- co-efficient of friction
ii    -- total mass of object 3
iii   -- x coordinate of object 3
iiii  -- y coordinate of target
iiiii -- final speed of system

Yes the function of the variables is commented, therefore it gets a good
nod from the grader, BUT THE VARIABLES MAKE NO SENSE.  Granted I tend
to go overboard by declaring the variable 'final_system_speed' (I *LIKE*
REXX), but I don't need a lookup table to find out what the variable
represents.

Granted, being at a school I see a lot of people making close to their
first attempts at programming.  But I've seen similar stuff on senior
and masters projects as well.  I hope that the programs written out
in industry are better.


> Roy Smith, {allegra,cmcl2,philabs}!phri!roy
> System Administrator, Public Health Research Institute
> 455 First Avenue, New York, NY 10016



Kenneth Ng: Post office: NJIT - CCCC, Newark New Jersey  07102
uucp !ihnp4!allegra!bellcore!argus!ken *** NOT ken@bellcore.uucp ***
bitnet(prefered) ken@orion.bitnet

ken@argus.UUCP (08/18/87)

In article <905@edge.UUCP>, doug@edge.UUCP (Doug Pardee) writes:
> In the Unix world, you can probably sell this idea.  In the non-Unix world,
> little details keep getting in the way.  Details like the biggest micro-
> controllers available (such as the 68HC11A8) only have 8K of ROM, and they
> cost tons more than the more common 2K chips like the 8049.  And if the
> company's gonna sell a few million of whatever the chips are going in,
> programming it in assembly language will save tens of millions of dollars.

This reminds me of something I read somewhere else.  Ada compiler writers
are having a fun time because a lot of applications go into embedded systems
where the criteria are to make it run with at least a given performance
and make it fit into 64K (!) of memory.  Compilers are getting better,
but people need to express things in a higher level language to get
these compilers to do their work better.
: -- 
: Doug Pardee, Edge Computer Corp; ihnp4!mot!edge!doug, seismo!ism780c!edge!doug



Kenneth Ng: Post office: NJIT - CCCC, Newark New Jersey  07102
uucp !ihnp4!allegra!bellcore!argus!ken *** NOT ken@bellcore.uucp ***
bitnet(prefered) ken@orion.bitnet

dg@wrs.UUCP (David Goodenough) (08/18/87)

In article <4180@ncoast.UUCP> robertd@ncoast.UUCP (Rob DeMarco) writes:
>    However, logically speaking, an assembler program is difficult to follow
>and grasp. You would HAVE to "comment fiendishly" so the person can see what
>it is doing. Logically on the human mind, a statement like this:
>
>    IF A = 8 THEN GOTO 5000
>
>is a little easier to follow then this:
>
>    CPI 8H
>    JZ 0C00H

I also do a fairly large amount of work in assembler, and I've found a very
clean, simple method of commenting & explaining what's going on.

Step 1:		Write & debug the code in C

Step 2:		Copy the C source to a .Z file (assembler source)

Step 3:		Put a ';' (comment start character) in front of each line

Step 4:		Produce the opcodes to do what the C does

Step 5:		Debug (99% of the time with a listing in hand)

So typical C code might be:

strncpy(dest, source, count)
char *dest, *source;
 {
    while (count-- && (*dest = *source))
     {
	dest++;
	source++;
     }
    *dest = 0;
 }

And the output:

;strncpy(dest, source, count)
.var	#dest	6		; offset from ix of dest
.var	#source	8		; offset from ix of source
.var	#count	6		; offset from ix of count
;char *dest, *source;
.extern	_strncpy
_strncpy:
	call	#csv		; set up frame pointer
	ld	c,(ix + #count)	; get count to bc
	ld	b,(ix + #count + 1)
	ld	e,(ix + #source); get source to de
	ld	d,(ix + #source + 1)
	ld	l,(ix + #dest)	; get dest to hl
	ld	h,(ix + #dest + 1)

/* as an aside, I use macros for the three ld pairs above:
	load	b,c,#count
 * which expands to the first load pair */
; {

loop:
	ld	a,b
	or	c
	jr	z,break		; exit loop if count == 0
	dec	bc		; count--

	ld	a,(de)
	ld	(hl),a		; copy a byte
	or	a		; and test for zero
	jr	z,break		; exit if zero byte at end of string

;    while (count-- && (*dest = *source))
;     {
	inc	de
;	 dest++;
	inc	hl
;	 source++;
	jr	loop
;     }
break:				; we always hit here with zero in a
	ld	(hl),a		; so save a zero byte to end
;    *dest = 0;
	jp	#cret		; clean up stack & return
; }

Now any one who can't read and understand that with a minimal knowledge
of z80 assembler needs to go back to school.
--
		dg@wrs.UUCP - David Goodenough

					+---+
					| +-+-+
					+-+-+ |
					  +---+

roy@phri.UUCP (Roy Smith) (08/20/87)

In article <309@wrs.UUCP> dg@wrs.UUCP (David Goodenough) describes how
he first writes his assembler code in C, then hand translates it into
assembler and keeps the C source around in the assembler source file as
comments.

	When I took my first microprocessor course, we worked with 6800s,
into which you had to key the machine code in hex.  Like David, I found the
best way to get the assembler code written was to write it first in
simplish C and then hand-compile it.  The problem with this approach is
that it removes the major incentive to write assembler these days; to
fine-tune that very small fraction of your code that runs the most, or to
do things that you just can't do in C (like executing a bus reset or
wait-for-interrupt instruction).  Once you start the fine tuning process,
the original C code doesn't correspond to the assembler on a one-to-one, or
even one-to-many basis anymore.
-- 
Roy Smith, {allegra,cmcl2,philabs}!phri!roy
System Administrator, Public Health Research Institute
455 First Avenue, New York, NY 10016

gtchen@faline.bellcore.com (George T. Chen) (08/20/87)

In article <> elg@killer.UUCP (Eric Green) writes:
>...As for SIZE... I
>estimate that my 5,000 lines of carefully crafted 6502 assembly language,
>could be implemented inmuch less than 1,000 lines of "C" (at an equivalent
>commenting and readability level, of course -- no stacking the deck HERE!).

But I'm sure the actual piece of executable code in orders of magnitude
smaller than the equivalent C program.  Also, I've assumed that since you
did the program in assembly, then it will probably run faster.  For that
matter, any program done in any HLL can be done in assembly and made to
run as fast if not faster.

doug@edge.UUCP (Doug Pardee) (08/20/87)

>>[Comment that Microsoft Basic and Lotus 1-2-3 wouldn't have been successful
>> if they weren't written in assembler.]
>
>All of these could have been easily implemented in an HLL, if it wasn't for
>the fact that they had to have suitable performance on a machine/OS
>combination that forced ad hoc limitations on the software.

The scene:  France, toward the end of the 18th century.  In the Palace, we
            find Marie Antoinette seated in front of an antique Louis XIV
            writing desk.  She is dressed in the excessive style we expect,
            with ruffles and lace everywhere.  Except she isn't wearing high
            heels, she's wearing sandals.

            As we zoom in on the writing desk, we see a Unix terminal.  Marie
            is playing Rogue.

[A guard rushes in]  "Your highness!!"

      [Marie removes her Walkman headphones, but doesn't look up from the
      terminal.  She seems distracted and annoyed.]  "Yes, what is it now?"

"Your Highness!  The peasants are revolting!"

      "They certainly are.  Where do they get their clothes, the Salvation
      Army?  And why do you interrupt me with such nonsense?"

"No Your Highness!  The peasants are rioting!  They say that your C program
won't run on their PC's!  They are marching in a ring all around the Palace,
shouting and making oinking noises!"

      [Marie still does not turn away from her terminal.]  "Aaarrgh!  Peasants
      are so STUPID!  Look, I don't have the time to deal with them now.  Just
      go out and explain to those idiot peasants that all they have to do is
      to port the program to their VAXen."  [She puts the headphones back on.]
-- 
Doug Pardee, Edge Computer Corp; ihnp4!mot!edge!doug, seismo!ism780c!edge!doug

tim@amdcad.AMD.COM (Tim Olson) (08/21/87)

In article <1305@faline.bellcore.com> gtchen@faline.UUCP (George T. Chen) writes:
+-----
|But I'm sure the actual piece of executable code in orders of magnitude
|smaller than the equivalent C program.  Also, I've assumed that since you
|did the program in assembly, then it will probably run faster.  For that
|matter, any program done in any HLL can be done in assembly and made to
|run as fast if not faster.
+-----

Only if the person writing the assembly language is very good.  The new
highly-optimizing C compilers are becoming *very* good at what they do. 
For example, one compiler I am familiar with compiled the code fragment:

	if (x[i] > x[i+1]) {
		temp = x[i];
		x[i] = x[i+1];
		x[i+1] = temp;
	}

to:
	const	base, _x		; calculate address of x[i]
	consth	base, _x
	sll	temp, i, 2
	add	base, base, temp
	load	val1, base		; get value of x[i]
	add	base2, base, 4		; calculate address of x[i+1]
	load	val2, base		; get value of x[i+1]

	cpgt	temp, val1, val2	; perform "if"
	jmpf	temp, $endif
	nop

	store	val1, base2		; swap operands
	store	val2, base



Note that the compiler optimized the array calculation expressions to
reuse a common sub-expression (x[i]), and that it totally optimized away
the temp variable used to swap the values!  I don't think you could
write it in assembly language any better than that.

	-- Tim Olson
	Advanced Micro Devices
	(tim@amdcad.amd.com)

peter@sugar.UUCP (Peter da Silva) (08/21/87)

In article <904@edge.UUCP>, doug@edge.UUCP (Doug Pardee) writes:
> True.  But this is cherry-picking for the example which best illustrates
> your point.  Counter-example: this line of 80x86 assembler expands into 
> several lines of just about any HLL:
>
>   REP MOVSB
> 
> When you count HLL lines, don't forget all of those lines that don't even
> generate any code at all.  How about the ever-popular C line, "}"?

And when you count assembly lines, add in all the ones needed to set up
for that instruction. Particularly if you have to load adresses of subroutine
arguments and add offsets to array locations...

The big loss in assembly is all that glue you have to add. How about the
plain old 'C' fragment:

	printf("Hello world.\n");

I don't know 80x86 assembly very well, so how about PDP-11, a much tighter an
easier to deal with instruction set than 80x86:

HELLO:	.ASCII	/Hello World./
	.BYTE	12,0
	.EVEN

	...

	MOV	#HELLO,-(SP)
	JSR	PC,_PRINTF
	TST	(SP)+

> That is petty stuff, though.  The real point is that some applications
> are "naturals" for the HLL, in which case I say DO use the HLL.  But for
> many others you have to go out of your way to accomplish the task, and
> that usually means extra HLL code.

The only application I've found that was a natural for Assembly was
imnplementing FORTH. The other place you need assembly (as opposed to
preferring it for speed or space) is dealing with an assembly-style
interface to an operating system.

> >Assembler also suffers ... the lack of direct support for record structures
> using.  These record structures (often called DSECTS in assembly) are
> available with IBM 360/370 assemblers, and with the Microsoft assembler for
> the IBM PC.  No doubt with other assemblers too.

A DSECT is more like a FORTRAN common block than a structure. Neither quite
fills the bill when only a structure will do.

> Unfortunately, in the Unix universe it is assumed that nobody programs in
> assembler, so Unix assemblers tend to be unusable trash.  A vicious cycle.

They do tend to be reliable and unsurprising, something that can't be said for
PC-DOS assemblers. And a macro package (like M4) makes a lot of difference.
I much preferred M4 and AS to Macro-11 when I ported John James' FIG-FORTH
to the PDP-11.

> I'm trying to make two distinct points here:  1) one of the biggest reasons
> that HLLs are used for applications that should have been done in assembly
> is programmer laziness.

The only example of this I can think of is that 'C' implementation of FORTH,
which was done more as an excersize than anything else.
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter (I said, NO PHOTOS!)

mpl@sfsup.UUCP (M.P.Lindner) (08/21/87)

In article <1305@faline.bellcore.com>, gtchen@faline.UUCP writes:
> But I'm sure the actual piece of executable code in orders of magnitude
> smaller than the equivalent C program.  Also, I've assumed that since you
> did the program in assembly, then it will probably run faster.  For that
> matter, any program done in any HLL can be done in assembly and made to
> run as fast if not faster.

The "real goal" is the performance per dollar of a program.  I doubt that
the C program is "orders of magnitude" larger than the assembly.  In my
experience, C programs are usually 20-80% larger than a carefully designed
assembler program.  Obviously assembler can be made at least as fast, but I've
seen assembler programs shrink when rewritten in C as well.  The fact that
the program in question is 5 times smaller *source* wise means that it is
at least 5 times easier to maintain (since it takes <= 1/5 the time to read
and the complexity is most likely smaller).  If a few percent (or even a
factor of a few times) in size and performance are a hot issue, buy more memory
or a faster processor, it's cheaper than the programming effort to squeeze
out the performance, especially if the program must be ported and maintained.

mwm@eris.BERKELEY.EDU (Mike (My watch has windows) Meyer) (08/22/87)

In article <1305@faline.bellcore.com> gtchen@faline.UUCP (George T. Chen) writes:
<For that matter, any program done in any HLL can be done in assembly
<and made to run as fast if not faster. 

Of *course* it can be made to run as fast. Just tell your compiler to
give you the assembler source listings, and viola, you've got an
assembler program that runs as fast as the HLL version. Who cares.

As for making it faster, the statement "almost any program done in any
HLL can be done in assembly and made to run faster" is true. Then
again, so is the even more general "almost any program can be made to
run faster." A different special case of this is "almost any program
done in assembler can be made to run faster in an HLL."

One way to make an HLL program run faster is to let the compiler turn
it into assembler, then hand-tune the assembler. On the other hand,
one way to make an assembly program run faster is to translate it to
an HLL, then tune the algorithms - or better yet, choose a faster one.
I am aware of examples of both.

But "run faster" or "be smaller" isn't the right question. The right
question is "is it fast/small enough now?" If your interpreted LISP is
fast enough for the application, then it's fast enough, and you don't
need to spend more time on it. If it isn't, then you work on making it
faster - compiling it, translating critical sections to assembler,
etc. On the other hand, if your carefully hand-crafted assembler isn't
fast enough, then you've got to do something to make it faster.

Finally, speed isn't the only criterion. Time to market, competition,
portability, availability, familiarity, etc. are all important. If
you're trying to squeeze something onto a processer+ram chip,
assembler may be the only rational choice. If you're writing for a
large Burroughs box, you may not *have* an assembler.

This is why it pays for a programmer to be familiar with many
languages (and other tools): it gives them a better ability to choose
the right tool for the job at hand.

	<mike
--
Must have walked those streets for hours,		Mike Meyer
In the dark and in the cold,				mwm@berkeley.edu
Before I really could accept,				ucbvax!mwm
There's no place called hope road.			mwm@ucbjade.BITNET

elg@killer.UUCP (Eric Green) (08/22/87)

in article <17981@amdcad.AMD.COM>, tim@amdcad.AMD.COM (Tim Olson) says:
> In article <1305@faline.bellcore.com> gtchen@faline.UUCP (George T. Chen) writes:
> +-----
> |But I'm sure the actual piece of executable code in orders of magnitude
> |smaller than the equivalent C program.  Also, I've assumed that since you
> |did the program in assembly, then it will probably run faster.  For that
> |matter, any program done in any HLL can be done in assembly and made to
> |run as fast if not faster.
> +-----
> Only if the person writing the assembly language is very good.  

I must agree, with reservations. Note that my 5,000 lines of assembly language
assembles down to 7,000 bytes of 6502 machine code.  A "C" compiler for a
6502-based machine is a real porker... for example, a simple 1,000 line
text-formatter program (included with my "C" compiler) compiles down to about
25K of machine code.

However, when we are talking about real machines, with architectures designed
from the start to support high level languages (Chuck Peddle thought his
little chip would be used in electronic ovens, fer chrissakes, he had no idea
anybody could wrap a COMPUTER around it!), it's a different story.  For
example, I was unsatisfied with the performance of Jove on the Pyramids at
school. So I profiled it, and decided I would re-code the hot-spots into
assembly language. Well, to make a long process short, after printing out the
.s file and looking at a particular hot spot (the cursor positioning code),
there wasn't any darned way under the heavens for me to do much better than
the compiler had done... I figured a way of eliminating maybe 5 instructions
out of 50, and the resulting code didn't run appreciably faster (still
accounted for about the same percentage of CPU). Re-tooling the algorithm so
that the full cursor-positioning routine wasn't called for every darned
keystroke, would have saved jillions of microseconds more time than hitting
this particulr hot spot (alas, Jove is an example of a program that's nigh
unreadable... nowhere does he tell the PURPOSE of any particular variable,
file, or subroutine, leading to wild guesses as to what he's trying to do). 

Anyhow, after that, I looked at the output of several small utility programs
that I'd written, using various levels of the optimizer. Most of them, I
couldn't do a darn bit better by hand (I'm no expert in 90x assembler, but I
have written a couple thousand lines in it, so I'm no novice, either).
--
Eric Green   elg%usl.CSNET     Ollie North for President:
{cbosgd,ihnp4}!killer!elg      A man we can believe (in).
Snail Mail P.O. Box 92191      
Lafayette, LA 70509            BBS phone #: 318-984-3854  300/1200 baud

jfh@killer.UUCP (The Beach Bum) (08/23/87)

that just about says it.  i like assembly for very time critical things,
but i don't want to write applications in assembler.  the best thing
you can do with assembler is write a good compiler, and then promptly
rewrite that in your high level language.

as for the cost, the book `The Mythical Man Month - Essays in Software
Engineering' is an excellent place to start if you actually believe in
saving money by writing assembler.

- john.
-- 
John F. Haugh II		HECI Exploration Co. Inc.
UUCP:	...!ihnp4!killer!jfh	11910 Greenville Ave, Suite 600
"Don't Have an Oil Well?"	Dallas, TX. 75243
" ... Then Buy One!"		(214) 231-0993

pf@diab.UUCP (Per Fogelstrom) (08/24/87)

In article <17981@amdcad.AMD.COM> tim@amdcad.UUCP (Tim Olson) writes:
>
>Only if the person writing the assembly language is very good.  The new
>highly-optimizing C compilers are becoming *very* good at what they do. 
>For example, one compiler I am familiar with compiled the code fragment:
>
>	if (x[i] > x[i+1]) {
>		temp = x[i];
>		x[i] = x[i+1];
>		x[i+1] = temp;
>	}
>
>to:
>	const	base, _x		; calculate address of x[i]
>	consth	base, _x
>	sll	temp, i, 2
>	add	base, base, temp
>	load	val1, base		; get value of x[i]
>	add	base2, base, 4		; calculate address of x[i+1]
>	load	val2, base		; get value of x[i+1]
>
>	cpgt	temp, val1, val2	; perform "if"
>	jmpf	temp, $endif
>	nop
>
>	store	val1, base2		; swap operands
>	store	val2, base
>
>
>
>Note that the compiler optimized the array calculation expressions to
>reuse a common sub-expression (x[i]), and that it totally optimized away
>the temp variable used to swap the values!  I don't think you could
>write it in assembly language any better than that.

Oh dear! This really confirms what i allways suspected about risc cpu's.
Very happy that i've givi'n up ass'(mbly) programming :-))))).

This example should really scare away the "assembly programmers"! TWELVE !!
instructions for doing something that should not take more than FIVE !!
And keeping track of the register contents even if they have mnemonic names!
I have tested the example on our own C-compiler genereating code for the
famous (:-)) NS32000 cpu, and it throws this out:

	cmpd	4(r1)[r0:d],r1[r0:d]
	bge	donotdothis
	movd	r1[r0:d],r2
	movd	4(r1)[r0:d],r1[r0:d]
	movd	r2,4(r1)[r0:d]

Before You start to flaming me about performence; I just wanted to show the
difference between a risc and a cisc's solution to the same HLL code. I think
my example is easier to read, but it does not justify that it should be
written in assembler rather than C.

A bad compiler should not justify writing a program in assembly. Even if
the generated code size sticks in your eyes. The extra time spent on
writing the same program in assembly is a waste, unless there are aspects
of performence put into it. Compilers improve (mostly) and if you are
lucky, you might be able to recompile the program with a better compiler later.
(I've been using the first 'PLM' compiler for the i8008 and i8080. It was
a terrible thing. It was trying to drown the programmer in machine code.
BUT! it improved, generating better code, and fewer bugs !).

I have seventeen(17) years of experience in assembly programming. (My first
on an IBM 1401, if that can be called assembly :-)). I have worked with the
development of three real time operating systems, the last one a UN*X SV
compatible and in "C". I've spent a whole summer squezing 6 kbytes out of
a 20 kbytes basic interpreter for a PC (and that before the IBM era).. Guess
how that code looked after that :-).So i think i have a pretty good idea
about the difference between assembly and HLL.

So let the suicide-makers program in assembly, even if they don't have to.
I don't bother unless i have to maintain any of their code.

Conclusion: One should have *very* good reasons (read "very high speed
	    requirements") for using assembly. People defending assembly
	    for large programming projects does'nt belive in porting.
	    The just belive that there is only one kind of cpu type
	    on the market. Programmers should spend more time on writing
	    comments explaining what the program does and how, than
	    writing "clever" assembly code that no one exept an "expert"
	    can understand. Using the same time effort for writing the
	    same program in assembly and in some HL- language "should"
	    produce a better documented program in HLL.

	AND REMEMBER !!!!!!!  NO PROGRAM LANGUAGE IS SELF-DOCUMENTING !!!!
	How understandable and maintinable a program is, depends *ONLY* on
	how good the documentation is. Nonsens comments like "moving this
	data here and that data there" is not documentation, it's filling.
	Explain *WHY* i'ts moved etc.!

   ** ASK ME !   I WILL SHURLEY VOTE FOR HLL  **
-- 
Per Fogelstrom,  Diab Data AB
SNAIL: Box 2029, S-183 02 Taby, Sweden
ANALOG: +46 8-7680660
UUCP: seismo!mcvax!enea!diab!pf

daveb@geac.UUCP (Brown) (08/28/87)

  Once upon a time, there was an Ability(tm) and an Enable(tm) for the
IBM Poisonous Computer.  

  Ability was written in a HLL with a few
assembler modules.  Enable was, according to its publicists, written
in assembler.
  The second version of Ability used a VMM written by Andrew Forber.
Enable used an unspecified overlay-swapping scheme.  
  Ability's HLL compiler produced mildly unimpressive code. Disassemblys of 
Enable looked *utterly beautiful*.

  The first Ability ran slower than Enable.  As one would expect.
  The second Ability ran faster on large-sized machines and slower on
medium-sized machines. As you might _not_ expect.
  I know that better algorithms can speed up processing, but surely
VMMs are slower (even Andrew agreed that it might be slower when he
proposed it).  

		Wha hoppen?

 --dave (file i/o) collier-brown

ps: Ability (actually Ability Plus, the second version) is still in
production and being advertized.  Enable may still exist, but I
haven't seen it lately...

-- 
 David Collier-Brown.                 {mnetor|yetti|utgpu}!geac!daveb
 Geac Computers International Inc.,   |  Computer Science loses its
 350 Steelcase Road,Markham, Ontario, |  memory (if not its mind)
 CANADA, L3R 1B3 (416) 475-0525 x3279 |  every 6 months.