[net.arch] Using C as an aid to hand writing assembler

roy@phri.UUCP (Roy Smith) (05/07/86)

In article <399@ccird1.UUCP> rb@ccird1.UUCP (Rex Ballard) writes:
> [...] C was written for PDP-11s, as sort of a GENERIC ASSEMBLER.  When
> reduced to it's simplest constructs, that is exactly what C is.

	Some years ago when I was learning 6800 assembler (anybody remember
D2 kits?) I used to first write everything in C and then hand compile it
into M6800 asm.  When I told my professor (are you reading this Professor
Efe?) that I did this instead of drawing flow-charts, he laughed at me, but
as long as you keep your code simple, the conversion is trivial and can be
done in your head as fast as you can write down the asm code.  Perhaps the
simplicity of the M6800 (dare I call it a RISC machine? :-)) makes this
easier than for something like a vax, but I can still do it; let's see:

	char i, j;
	j = 0;
	for (i = 0; i <= 10; i++)
	        j = j + i;

	clr	j
loop1:  clr	i
	cmp	i, #10
	bge	out
	lda	j
	adda	i
	sta	j
	lda	i
	inca
	sta	i
	bra     loop1:
out:
-- 
Roy Smith, {allegra,philabs}!phri!roy
System Administrator, Public Health Research Institute
455 First Avenue, New York, NY 10016

dan@rna.UUCP (Dan Ts'o) (05/07/86)

> 	Some years ago when I was learning 6800 assembler (anybody remember
> D2 kits?) I used to first write everything in C and then hand compile it
> into M6800 asm.  When I told my professor (are you reading this Professor
> Efe?) that I did this instead of drawing flow-charts, he laughed at me, but
> as long as you keep your code simple, the conversion is trivial and can be
> done in your head as fast as you can write down the asm code.  Perhaps the
> simplicity of the M6800 (dare I call it a RISC machine? :-)) makes this
> easier than for something like a vax, but I can still do it; let's see:
> 
> 	char i, j;
> 	j = 0;
> 	for (i = 0; i <= 10; i++)
> 	        j = j + i;
> 
> 	clr	j
> loop1:  clr	i
> 	cmp	i, #10
> 	bge	out
> 	lda	j
> 	adda	i
> 	sta	j
> 	lda	i
> 	inca
> 	sta	i
> 	bra     loop1:
> out:

	Not too good, I'm afraid. The loop1 label is misplaced - you "clr i"
on every iteration. Also #10 is octal 8 instead of 10. You probably don't want
the colon at the end of the "bra" statement. You don't want "bge out" but
"bgt out" (since you say i <= 10). And finally, i and j should be local
variables on the stack. I can see why your professor laughed.

dyer@atari.UUcp (Landon Dyer) (05/08/86)

In article <491@rna.UUCP>, dan@rna.UUCP (Dan Ts'o) writes:
> > 	Some years ago when I was learning 6800 assembler (anybody remember
> > D2 kits?) I used to first write everything in C and then hand compile it
> > into M6800 asm.

I used exactly the same technique writing video game cartridges for
the "old" Atari --- write a module in a kind of psuedo-C, then hand
compile it into 6502 assembly.  The trick was that each function had
three local variables called A, X and Y; it really WAS high level
assembly language.  My roommate called me "the world's best optimizing
C compiler for the 6502."  It worked well.

You can laugh, but I made the company millions of dollars this way.
(It's not MY fault the old Atari blew it --- the engineers were making
money but the marketing types out-numbered us three to one!  Grrr.)

----------------

Here's a perverse thought: Has anyone done any research on
architechures to help people writing /assembly language/?  (Maybe the
PDP-11, VAX or IBM-370 architechures are optimal, or maybe no one has
ever considered making life easier for those who spend their lives
coding "down unda.")
-- 

Landon Dyer					"If Business is War, then 
Atari Corp.					  I'm a Prisoner of Business!"
... {hoptoad,lll-crg!vecpyr}!atari!dyer		"Quantity is Quality!"

@hpislx.UUCP (05/08/86)

This message is empty.

csg@pyramid.UUCP (Carl S. Gutekunst) (05/08/86)

In article <2336@phri.UUCP> roy@phri.UUCP (Roy Smith) writes:
>... I used to first write everything in C and then hand compile it
>into M6800 asm....
>as long as you keep your code simple, the conversion is trivial and can be
>done in your head as fast as you can write down the asm code.  Perhaps the
>simplicity of the M6800 makes this easier than for something like a vax....

Interestingly enough, this is exactly the way Roy Harrington wrote all of Z80
Cromix. The entire kernel was written first in C, then hand compiled into Z80
assembler. It's the only assembler program of that magnitude (40K of code)
that I've ever worked with that was easy and pleasant to maintain. (Roy's C
coding was very clean as well, which helped.) 

The penalty was that many of the C constructs needed for a Unix-like OS did
not map well into the Z80's instruction set, or required use of the highly
inefficient IX and IY instructions. Hence the OS was both bigger and slower
than it could have been. On the other hand, the tty driver was written using
more "classical" coding style, with all the usual sorts of "clever" tricks you
can do in assembler. It was slower than frozen mud, buggy, and impossible to
maintain. 

<csg>

sr@pyuxv.UUCP (S Radtke) (05/09/86)

>	Some years ago when I was learning 6800 assembler (anybody remember
>D2 kits?) I used to first write everything in C and then hand compile it
>into M6800 asm.  When I told my professor (are you reading this Professor
>Efe?) that I did this instead of drawing flow-charts, he laughed at me, but
>as long as you keep your code simple, the conversion is trivial and can be
>done in your head as fast as you can write down the asm code.  Perhaps the
>...

I just read an article from IEEE Transactions on Software Engineering
Feb.,1986 by Peter Henderson, "Functional Programming, Formal Specification,
and Rapid Prototyping". Except for the hand compilation,
which could be avoided, you were doing a similar thing- using a high level
language as a formal specification for a lower level language. Your code
was an executable specification and allowed rapid prototyping to influence
the design decisions at an early point.

Steve Radtke
Bell Communications Research
Piscataway, NJ

franka@mmintl.UUCP (Frank Adams) (05/09/86)

In article <2336@phri.UUCP> roy@phri.UUCP (Roy Smith) writes:
>	Some years ago when I was learning 6800 assembler (anybody remember
>D2 kits?) I used to first write everything in C and then hand compile it
>into M6800 asm.  When I told my professor (are you reading this Professor
>Efe?) that I did this instead of drawing flow-charts, he laughed at me,

Well, he shouldn't have.  Writing "pseudo-code" first (it needn't be
compilable or even in a well-defined language) is a standard design
technique, both for assembly code and for code in higher level languages.
In my experience, it is a lot more common than flow-chart writing.  Flow
charts are appropriate only for the rare program with an inherently very
complex flow of control.  In other words, if you find you need to write a
flow chart to get the logic right, you should first try to go back and
redesign the algorithm, or modularize it better.

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108

kludge@gitpyr.UUCP (Scott Dorsey) (05/10/86)

In article <261@atari.UUcp> dyer@atari.UUcp (Landon Dyer) writes:
>Here's a perverse thought: Has anyone done any research on
>architechures to help people writing /assembly language/?  (Maybe the
>PDP-11, VAX or IBM-370 architechures are optimal, or maybe no one has
>ever considered making life easier for those who spend their lives
>coding "down unda.")

   Ever seen the UCSD Pascal system?  It had a Pascal compiler which
compiled down to P-Code, which was like a machine code with high-
level language features.  The P-Code was then interpreted by the
machine, in my case an Apple II.  I wrote an assembler in Pascal which
allowed you to code directly in P-Code.  Compared to the 6502, it
was pure joy... array support, real numbers.  It was slow, but better
than either the Pascal or the Basic.
   I know what I like in an architecture.  I could build an instruction
set that is just right for me.  However, other people might not like
it.   Assembly coding is a very personal thing.  I think that something
like a P-code might be in order to allow any person to develop code
using his 'own' instruction set, and have it compile to machine code
for other machines.  It would be mindblowingly slow, especially because
th architecture I would use would be unlike the machines I am forced
to work on.
    BCD support?  Come on.
    And, no, I don't like using floating-point instructions to
    manipulate characters. 
-- 
-------
Disclaimer: Everything I say is probably a trademark of someone.  But
            don't worry, I probably don't know what I'm talking about.

Scott Dorsey       " If value corrupts
kaptain_kludge         then absolute value corrupts absolutely"

ICS Programming Lab (Where old terminals go to die), Rich 110,
Georgia Institute of Technology, Box 36681, Atlanta, Georgia 30332
...!{akgua,allegra,amd,hplabs,ihnp4,seismo,ut-ngp}!gatech!gitpyr!kludge

greg@utcsri.UUCP (Gregory Smith) (05/13/86)

In article <491@rna.UUCP> dan@rna.UUCP (Dan Ts'o) writes:
>> 	Some years ago when I was learning 6800 assembler (anybody remember
>> D2 kits?) I used to first write everything in C and then hand compile it
>> into M6800 asm. ...
>> simplicity of the M6800 (dare I call it a RISC machine? :-)) makes this
>> easier than for something like a vax, but I can still do it; let's see:
>> 
>> 	char i, j;
>> 	j = 0;
>> 	for (i = 0; i <= 10; i++)
>> 	        j = j + i;
>> 
>> 	clr	j
>> loop1:  clr	i
>> 	cmp	i, #10
>> 	bge	out
>> 	lda	j
>> 	adda	i
>> 	sta	j
>> 	lda	i
>> 	inca
>> 	sta	i
>> 	bra     loop1:
>> out:
>
>	Not too good, I'm afraid. The loop1 label is misplaced - you "clr i"
>on every iteration. Also #10 is octal 8 instead of 10. You probably don't want
>the colon at the end of the "bra" statement. You don't want "bge out" but
>"bgt out" (since you say i <= 10). And finally, i and j should be local
>variables on the stack. I can see why your professor laughed.

If you must flame, do it properly. As I remember, in Motorola assembler,
10 is decimal, $10 is hex. Besides, you don't expect that sort of detail
in a news posting, do you? You missed the biggie completely: there is no
such thing as `cmp i,#10' in 6800 code. I believe `inc i' could have been
done, instead of lda/inc/sta.

Hand-compiling is definitely a good idea when a good compiler cannot
be had. When you write the C code, you deal at a reasonably high level
of abstraction; when you translate, you worry about details only and forget
the higher meaning. One major problem is with maintenance: when people
modify the assembler code, they don't bother changing the C code!

There are cases where real compilers cannot be had which are good enough.
If someone knows of a C compiler for Z80 or 8080 which can produce code
half as good as that produced by hand, I would like to hear about it. I
am sure it could be done - but nobody would pay you enough to make it
worth the effort. It would almost be an AI project!

While debugging, you have to figure out if bugs are caused by problems
in the C code ( many of these will be found during the hand-compile ) or
by incorrect compilation. If you have a real compiler, no matter how
horrible, you can often debug the C code with that before hand compiling,
and then hand-compile in stages. 'In stages' implies that the parameter
passing convention for the hand code follow that of the compiler, which
may not be desirable - especially on the kind of machine we are talking
about here.


-- 
"Canabee be said2b or not2b anin tire b, if half thabee isnotabee, due2
somain chunt injury?" - Eric's Dilemma
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

munck@faron.UUCP (Robert Munck) (05/13/86)

In article <201@pyuxv.UUCP> sr@pyuxv.UUCP (25220-S Radtke) writes:
>
>>	Some years ago when I was learning 6800 assembler (anybody remember
>>D2 kits?) I used to first write everything in C and then hand compile it
 
  As a minor addition to the technique (and to show that you're not
forced to expose yourself to possible chromosome damage by using C)
I wrote the Navy's standard executive for their 16-bit line of computers
(AN/UYK-20, -44, AN/AYK-14) first in Ada (as it existed in 1979).  Of
course, there were no Ada compilers then, so I hand-translated some of
the important algorithms -- task scheduling, memory allocation -- into
Pascal that I could compile and run.  This was used to debug and tune
them for speed.  Finally, I wrote some assembler macros supporting
IF-THEN-ELSE, looping, and subroutine invocation and hand-translated
the Ada/Pascal into assembler/macros.

  The contract was competitive: a team from an unnamed mainframe
manufacturer wrote their own version, but all in assembler.  There
was great emphasis on speed, so they wrote theirs as one giant
assembly program to avoid the overhead of subroutine calls.  Mine
was divided into 60-odd modules.  They spent their time on micro-
optimization of the assembly; I spent mine on the overall design.
Mine was about 10% faster.

   The OS I'm writing now, for the 80386, will be in Ada from start
to finish.  If, when it's up and running, I find that 90% of its
execution time is in 10% of the code (which is likely), I'll look
at that 10% for possible recoding of strategic modules in assembler.
I'll also keep the Ada routines that are replaced, for future
retargetting.
       -- Bob Munck

sd@erc3ba.UUCP (S.Davidson) (05/16/86)

> In article <201@pyuxv.UUCP> sr@pyuxv.UUCP (25220-S Radtke) writes:
> >
>  
>   As a minor addition to the technique (and to show that you're not
> forced to expose yourself to possible chromosome damage by using C)
> I wrote the Navy's standard executive for their 16-bit line of computers
> (AN/UYK-20, -44, AN/AYK-14) first in Ada (as it existed in 1979).  Of
> course, there were no Ada compilers then, so I hand-translated some of
> the important algorithms -- task scheduling, memory allocation -- into
> Pascal that I could compile and run.  This was used to debug and tune
> them for speed.  Finally, I wrote some assembler macros supporting
> IF-THEN-ELSE, looping, and subroutine invocation and hand-translated
> the Ada/Pascal into assembler/macros.
> 
Ada was used as a high level specification of microcode for the Intel 432.
At that time they also didn't have a compiler, so hand translated and
optimized it.  They even had to use an enhanced version of Ada to handle all
the things they wanted to do in microcode.  (Source - talk by Dan
Hammerstrom at the 14th Microprogramming Workshop).

I think this is a good technique for microprogramming where no compilers are
available.  Has anyone else used it?

-- 
Scott Davidson
AT&T Engineering Research Center
..!{allegra,ihnp4}!erc3ba!sd
(609) 639-2289
P.O. Box 900
Princeton, NJ 08540

roy@phri.UUCP (Roy Smith) (05/17/86)

	In article <491@rna.UUCP> dan@rna.UUCP (Dan Ts'o) flamed me for a
bunch of syntactic and semantic errors in my hand-assembly example.  A
while later, in article <2763@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith)
continued to find errors in my 6800 code.  The lesson here is that if you
are going to post something to the net, better make sure it is right.  Dan
and Greg are right that my translation was a mess.

	The point I was trying to make (and so far, I havn't seen anybody
who has disagreed with me) is that HLL's make great tools for helping write
assembler.  Once the code is written, the HLL version should be kept around
as documentation.

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

hoffman@hdsvx1.UUCP (05/24/86)

>>> 	Some years ago when I was learning 6800 assembler (anybody remember
>>> D2 kits?) I used to first write everything in C and then hand compile it
>>> into M6800 asm. ...


I used this technique in the late 70's at Texas Instruments, when I was given
a summer to code some mathematical utilities against some *very* tight size
and timing considerations.  I first wrote the code in FORTRAN (it was all we
had, plus it wasn't so bad for short math programs like that), debugged it
completely, then compiled it with the list option, and hand-optimized loops
and register usage.  It worked like gang-busters, and probably increased my
productivity by 200% since it only took me a month to do the whole set when
they had expected it to take three months-- especially since it was my first
contact with assembly language!

I used this technique again several years later to do some programming on a
Motorola 68000 -- not only is it fast, but it's a great way to learn a new
assembly language, and it provides an extra layer of testing and documentation.
I never have understood why everyone doesn't use it.  Even if your compiler
is a real dog, you can fix bad code that you understand a lot easier than you
can write good code from scratch.

Richard Hoffman
Schlumberger Well Services
hoffman%hdsvx1@slb-doll.csnet