Maker Pro
Maker Pro

C or Assembly

  • Thread starter Abstract Dissonance
  • Start date
D

Daniel Pitts

Jan 1, 1970
0
Actually _Real_ men program with switches and buttons :)
 
J

John Larkin

Jan 1, 1970
0
Actually _Real_ men program with switches and buttons :)

Real men build dams and chop down trees and sail ships. We're
engineers.

John
 
P

petrus bitbyter

Jan 1, 1970
0
John Larkin said:
Real men build dams and chop down trees and sail ships. We're
engineers.

John

So what do real engineers do?

petrus bitbyter
 
A

Andrew Merton

Jan 1, 1970
0
John said:
A program is easy to maintain if it's logical, has sensible data
structures, and most importantly if it's thoroughly and correctly
commented.

Hear, hear!
Most C programmers comment little if any, apparently by
tradition and training. My assembly programs are extensively commented
- roughly 4x as many characters of comment compared to code - and are
easy to understand and maintain years later.

If variables, functions etc are named properly, then code in high-level
languages is much more self documenting (than if it's not - this is not
necessarily in comparison to assembler), and the need for comments is
reduced. By no means removed.
And I always have a
single batch file, GO.BAT, that completely rebuilds the entire project
and makes a new rom file, and we archive all the tools.

Ahah - a Makefile! B-)
I think the one-operation-per-line and resulting ease of commenting
make assembly a lot easier to read than the
monkeys-pounding-typewriters look of C. If you read my comments,
you'll know exactly what's happening and why.

But you need so many lines! And the comments have to be kept up-to-date
and accurate (or they're worse than not having any at all), which adds
to the maintenance burden which is already exacerbated by having 10
times as many lines of code in the first place...
.SBTTL . XMAC : MACRO EXECUTION ENGINE

; THIS IS ENTERED WITH A0 AIMING AT A MACRO CODE FOLLOWED BY A
; PARAMETER LIST. THIS IS USUALLY IN VME SPACE, BUT CAN BE IN ROM
; WHEN THAT'S USEFUL. WE ALWAYS COPY THE COMMAND AND PARAMETERS
; INTO THE 'MAC' SPACE IN CPU RAM, TO ALLOW ROM INVOCATIONS AND
; TO SPEED UP MACRO EXECUTIONS, ESPECIALLY FOURIER FUNCTIONS.
;
; WE'LL TRY TO EXECUTE THE MACRO, AND WILL RETURN STATUS
; IN D7. B15 WILL BE UP IF WE DETECT AN ERROR.


XMAC: CLR.W AFLAG.W ; NUKE 'ADD WAVE' REQUEST

MOVE.W # 0FF00h, D7 ; ERROR CODE 255 WILL BE 'BAD MACRO'

MOVE.W (A0), D0 ; NAB CALLER'S COMMAND CODE
ANDI.W # 255, D0 ; ISOLATE LOW BYTE
CMPI.W # MAXIM, D0 ; CHECK AGAINST LIMIT
BHI BADMAC ; POST ERROR IF OUT OF RANGE.

; NOW COPY THE ENTIRE COMMAND BLOCK...

MOVEA.W # MAC, A1 ; AIM AT DESTINATION IN CPU RAM
MOVE.W # 110, D6 ; MAKE DBF COUNT FOR COMMAND+110 PARAMS

FILCH: MOVE.W (A0)+, (A1)+ ; COPY, WORDWISE.
DBF D6, FILCH

ASL.W # 1, D0 ; SCALE CMD * 2 FOR WORD LOOKUP
ADDI.W # DISMAL, D0 ; ADD IN TABLE START
MOVEA.W D0, A1 ; COPY TO AN ADDRESS REG

MOVEA.W (A1), A1 ; POP THE ROUTINE ADDRESS
JMP (A1) ; AND HOP TO IT.


; ALL COMMAND ERRORS JUMP HERE:

BADMAC: ORI.W # B15, D7 ; POST THE 'MACRO ERROR' CODE
CLR.B D7 ; AND NUKE 'COMMAND CODE' FIELD
RTS ; (BITS 8-14 HOLD ERROR CODES)

; AND SUCESSFUL MACROS EXIT HERE:

OKAY: CLR.W D7 ; HERE, INDICATE GOODNESS
RTS

.SBTTL . MACRO COMMAND DISPATCH TABLE

DISMAL: .WORD BADMAC ; 00 ILLEGAL COMMAND
.WORD FOURS ; 01 BUILD FOURIER SERIES
<<SNIP>>
.WORD URAM ; 26 TEST CPU SRAM

MAXIM = 26h ; LAST LEGAL MACRO CODE


I think this would be a fair replacement for the above code (but my C
and Assembler are both a bit rusty, and this is completely uncompiled
and untested so I'm probably wrong...):

#define MAXIM 0x26

int BADMAC(int *args) {
return 0x80ff;
}

/* other function definitions/prototypes... */

int *DISMAL[] = {
BADMAC,
FOURS,
...,
URAM
};

/* Given an index into the DISMAL table, and a 110-element array
of integer arguments, execute the specified function.

All the called functions must have the same signature as
BADMAC, above. */

int XMAC(int cmd, int *args) {

/* Check the parameter */
if (cmd > MAXIM) {
return 0x80ff;
}

/* Index the array and call the function */
return (DISMAL[cmd])(args);

}

IMO, the C is easier, shorter and more succinct. Being so much shorter,
it also will lead to fewer defects and therefore shorter development and
test times.

Note that I'm not saying this is the best way to do this in C...

I guess my real point is that since C programs are shorter, they need
less comments, but still need "enough".

JM2c...
 
J

John Larkin

Jan 1, 1970
0
John said:
A program is easy to maintain if it's logical, has sensible data
structures, and most importantly if it's thoroughly and correctly
commented.

Hear, hear!
Most C programmers comment little if any, apparently by
tradition and training. My assembly programs are extensively commented
- roughly 4x as many characters of comment compared to code - and are
easy to understand and maintain years later.

If variables, functions etc are named properly, then code in high-level
languages is much more self documenting (than if it's not - this is not
necessarily in comparison to assembler), and the need for comments is
reduced. By no means removed.
And I always have a
single batch file, GO.BAT, that completely rebuilds the entire project
and makes a new rom file, and we archive all the tools.

Ahah - a Makefile! B-)
I think the one-operation-per-line and resulting ease of commenting
make assembly a lot easier to read than the
monkeys-pounding-typewriters look of C. If you read my comments,
you'll know exactly what's happening and why.

But you need so many lines! And the comments have to be kept up-to-date
and accurate (or they're worse than not having any at all), which adds
to the maintenance burden which is already exacerbated by having 10
times as many lines of code in the first place...
.SBTTL . XMAC : MACRO EXECUTION ENGINE

; THIS IS ENTERED WITH A0 AIMING AT A MACRO CODE FOLLOWED BY A
; PARAMETER LIST. THIS IS USUALLY IN VME SPACE, BUT CAN BE IN ROM
; WHEN THAT'S USEFUL. WE ALWAYS COPY THE COMMAND AND PARAMETERS
; INTO THE 'MAC' SPACE IN CPU RAM, TO ALLOW ROM INVOCATIONS AND
; TO SPEED UP MACRO EXECUTIONS, ESPECIALLY FOURIER FUNCTIONS.
;
; WE'LL TRY TO EXECUTE THE MACRO, AND WILL RETURN STATUS
; IN D7. B15 WILL BE UP IF WE DETECT AN ERROR.


XMAC: CLR.W AFLAG.W ; NUKE 'ADD WAVE' REQUEST

MOVE.W # 0FF00h, D7 ; ERROR CODE 255 WILL BE 'BAD MACRO'

MOVE.W (A0), D0 ; NAB CALLER'S COMMAND CODE
ANDI.W # 255, D0 ; ISOLATE LOW BYTE
CMPI.W # MAXIM, D0 ; CHECK AGAINST LIMIT
BHI BADMAC ; POST ERROR IF OUT OF RANGE.

; NOW COPY THE ENTIRE COMMAND BLOCK...

MOVEA.W # MAC, A1 ; AIM AT DESTINATION IN CPU RAM
MOVE.W # 110, D6 ; MAKE DBF COUNT FOR COMMAND+110 PARAMS

FILCH: MOVE.W (A0)+, (A1)+ ; COPY, WORDWISE.
DBF D6, FILCH

ASL.W # 1, D0 ; SCALE CMD * 2 FOR WORD LOOKUP
ADDI.W # DISMAL, D0 ; ADD IN TABLE START
MOVEA.W D0, A1 ; COPY TO AN ADDRESS REG

MOVEA.W (A1), A1 ; POP THE ROUTINE ADDRESS
JMP (A1) ; AND HOP TO IT.


; ALL COMMAND ERRORS JUMP HERE:

BADMAC: ORI.W # B15, D7 ; POST THE 'MACRO ERROR' CODE
CLR.B D7 ; AND NUKE 'COMMAND CODE' FIELD
RTS ; (BITS 8-14 HOLD ERROR CODES)

; AND SUCESSFUL MACROS EXIT HERE:

OKAY: CLR.W D7 ; HERE, INDICATE GOODNESS
RTS

.SBTTL . MACRO COMMAND DISPATCH TABLE

DISMAL: .WORD BADMAC ; 00 ILLEGAL COMMAND
.WORD FOURS ; 01 BUILD FOURIER SERIES
<<SNIP>>
.WORD URAM ; 26 TEST CPU SRAM

MAXIM = 26h ; LAST LEGAL MACRO CODE


I think this would be a fair replacement for the above code (but my C
and Assembler are both a bit rusty, and this is completely uncompiled
and untested so I'm probably wrong...):

#define MAXIM 0x26

int BADMAC(int *args) {
return 0x80ff;
}

/* other function definitions/prototypes... */

int *DISMAL[] = {
BADMAC,
FOURS,
...,
URAM
};

/* Given an index into the DISMAL table, and a 110-element array
of integer arguments, execute the specified function.

All the called functions must have the same signature as
BADMAC, above. */

int XMAC(int cmd, int *args) {

/* Check the parameter */
if (cmd > MAXIM) {
return 0x80ff;
}

/* Index the array and call the function */
return (DISMAL[cmd])(args);

}

IMO, the C is easier, shorter and more succinct. Being so much shorter,
it also will lead to fewer defects and therefore shorter development and
test times.

Except that, in real life, it doesn't. See below.
Note that I'm not saying this is the best way to do this in C...

I guess my real point is that since C programs are shorter, they need
less comments, but still need "enough".


Not "enough". Your code has no top-level introduction. The list of
dispatch functions in neither numbered nor commented, so if I want to
know what the function code for "Gear" is, I have to count the list,
and there's no comment about what each one does. The def of MAXIM is
unconnected to the dispatch list, except by manual counting.

(Actually, MAXIM could be computed from actual list length, but I got
lazy here, and each dispatch pointer is numbered in plain sight
anyhow.)

I wind up programming a *lot* faster than most C programmers, if you
include "programming" to mean "fielding a bug-free program." Actually,
many C programmers take infinite time to meet this definition. I spend
very little time debugging embedded things, largely because the act of
commenting makes me consider exactly what I'm doing.

XP (extreme programming) demonstrates that it's worth using two
programmers, in front of one screen, to write code, simply because the
bug level is so much less. LOC/programmer-day is reduced by a factor
of 5 or so, and it's still worthwhile! They get the code right, but
they still leave no trail. When I comment, *I* am the second XP
programmer, and the bonus is the trail of correct, explicative
comments left for posterity.

The holy grail of self-commenting languages is crazy. Comments tell
why things are done, and code tells what was done. Programmers are
notoriously impatient and inarticulate, which is why they hate to
comment.

There's nothing really wrong with C as a language, apart from its
brutal ugliness, but accepted C practice is stunningly sloppy, and C
leads on on to C++ and other levels of abstraction.

Microsoft, who writes the OS and the compilers, one of the biggest
programming factories on the planet, has released something like
100,000 bugs in their various products. Clearly the existing
programming paradigm, what everybody is learning in "computer science"
classes, sucks.

John
 
A

Andrew Merton

Jan 1, 1970
0
I think one point is that Assembler *needs* more comments. In C, you
have (I think) at least 32 characters for each variable or function name
(anyone got K&R somewhere?); in Assembler you get 6-8 and no lowercase,
so a function can't be "Build_Gear" - it has to be "GEAR", and therefore
requires a comment.

Actually, I'd use "BuildGear()" these days (I've been Java-fied), and I
just realised that C-style would dictate "build_gear()" anyway, I think.
Oh well...
"D7" makes my point for me (I believe it's a register?) - it *needs* to
be commented for the reader to have any idea what's going on. Same with
the other registers...

BTW - I apologise for not noticing the form-feeds(?) in the code I quoted...
Except that, in real life, it doesn't. See below.


Not "enough". Your code has no top-level introduction.

True. The actual function does, though not as complete as yours. But
I'm not writing this for production (although as I rewrote it, I started
wondering whether it might not be useful for my robot(s)... :) ), and
assumed that it would be a small part of a larger gestalt... Sorry...
The list of
dispatch functions in neither numbered nor commented, so if I want to
know what the function code for "Gear" is, I have to count the list,
and there's no comment about what each one does. The def of MAXIM is
unconnected to the dispatch list, except by manual counting.

Fair enough. I would tend not to comment every line anyway - maybe the
first of each group of 4, just so I didn't have to type as many. Also,
numbering the last might come in handy some time...

Ok. This is compiled and slightly tested (using PICC Lite, and the
MPLAB Simulator):

int Bad_Code(int *args) {
return 0x80FF;
}

int Build_Fourier_Series(int *args) {
return 1;
}

int Add_Fourier(int *args) {
return 2;
}

int Build_Gear(int *args) {
return 3;
}

// An array containing the addresses of all the functions
// currently available. Unused entries will return 0x80FF
// (for historical reasons) if called.
int (*DispatchArray[])(int *args) = {
Bad_Code, // 0
Build_Fourier_Series,
Add_Fourier,
Build_Gear // 3
};

// Maximum index into the above array
#define MAXIM (sizeof DispatchArray/sizeof DispatchArray[0])

/* Execute the cmd-th function in the DispatchArray table,
passing in the (pointer to the) array of (16-bit) arguments.

All the called functions must (obviously) have the same
signature as Bad_Code(), above.

Calls out of range will return 0x80FF for historical reasons
*/

int Execute_Macro(int cmd, int *argList) {

/* Make sure not to index outside the array */
if (cmd >= (int)MAXIM) {
return 0x80ff;
}

/* Index the array to call the function */
return (DispatchArray[cmd])(argList);

}


void main(void) {

int myArgs[3] = {1,2,3}; // Dummy arguments

Execute_Macro(0, myArgs); // First valid entry in table
// but calling the error
// function
Execute_Macro(1, myArgs); // Something "useful"
Execute_Macro(3, myArgs); // Last valid entry
Execute_Macro(4, myArgs); // Outside the table

}

And I am ignoring the return from Execute_macro() simply because I
didn't have anything useful to do with it, including checking it...
Actually, I guess that should have been a series of

if (Execute_Macro(1, myArgs) != 1) {
do_error_stuff();
}
if (Execute_Macro(2, myArgs) != 2) {
do_error_stuff();
}

Ignoring everything except the actual XMAC function and its equivalent,
there are 6 lines (*including* braces) where something is executed in
the C version. (Some of the braces could be removed, but this is the
style I like; others have only syntactical use).

Comparing this to 15 lines (17 if I should be including the OKAY group)
where something can go wrong in the assembler version - how can it
possibly be quicker to develop and test the latter?
I wind up programming a *lot* faster than most C programmers, if you
include "programming" to mean "fielding a bug-free program."

Possibly you're one of the few programmers who are just more productive
than the average - there's a measured difference in productivity of
something like 10x(?) between the worst and the best (I think in
Peopleware, by Tom DeMarco)
Actually,
many C programmers take infinite time to meet this definition.

So do a lot of assembler programmers - I know, I've worked with some of
them... :)
The holy grail of self-commenting languages is crazy. Comments tell
why things are done, and code tells what was done. Programmers are
notoriously impatient and inarticulate, which is why they hate to
comment.

But given that self-documenting code would be a good thing, assembler
and its 8-character names falls rather short...
There's nothing really wrong with C as a language, apart from its
brutal ugliness, but accepted C practice is stunningly sloppy, and C
leads on on to C++ and other levels of abstraction.

Laid out properly, a C program tells you its logical structure (e.g. if
this condition is not met, skip down to here, etc) - I have never seen
an Assembler program that gave me that much help, even...

A lot of it's style, I suppose - I always recommend "Code Complete" for
people who want to do C (and just about any other programming, actually)
better. YMMV...

And C++ is the spawn of the devil... These days, C leads to Java... :)
Microsoft, who writes the OS and the compilers, one of the biggest
programming factories on the planet, has released something like
100,000 bugs in their various products. Clearly the existing
programming paradigm, what everybody is learning in "computer science"
classes, sucks.
I wonder how much (if any) of their code is still in assembler - I guess
MS C++ compiler is pretty good now :)

Actually, Steve McConnell, who wrote Code Complete, used to work for MS.
And you're assuming that what MS does is what everybody else does.
It's not.
 
J

John Larkin

Jan 1, 1970
0
I think one point is that Assembler *needs* more comments.

No language *needs* comments. People need comments.
In C, you
have (I think) at least 32 characters for each variable or function name
(anyone got K&R somewhere?); in Assembler you get 6-8 and no lowercase,
so a function can't be "Build_Gear" - it has to be "GEAR", and therefore
requires a comment.

My assembler allows 256-character symbols. I just don't like typing
long things filled with case shifts and underscores. I like any label
or variable name to be easily pronuncable.

Again, the code tells what was done, and the comments tell why.
Actually, I'd use "BuildGear()" these days (I've been Java-fied), and I
just realised that C-style would dictate "build_gear()" anyway, I think.
Oh well...

Why not

Build_Gear_Waveshape_Into_Wave_Table_With_Programmable_Missing_Teeth

That's what it does.

But then, the comments at the header of the GEAR routine explain it in
detail.


"D7" makes my point for me (I believe it's a register?) - it *needs* to
be commented for the reader to have any idea what's going on. Same with
the other registers...

There is no point in describing D7 is a 32-bit register; that's
obvious to anyone who knows how to program a 68K in assembly. I
haven't seen an "Introduction to the C language" embedded in any of
the C programs I've read. Do you explain the meaning of "int" each
time before you use it? (Actually, "int" is a lot more ambiguous than
"D7") Again, comments shouldn't be used to explain the language;
that's a given, and it's in the books. Comments explain *why* we're
doing things.

BTW - I apologise for not noticing the form-feeds(?) in the code I quoted...

All my programs are paged for easy reading. And there's a table of
contents at the beginning of the program listing, based on the
embedded .SBTTL directives (this idea cribbed from MACRO-11.) So the
entire program can be seen in one beautiful, indexed, heavily
commented fanfold paper listing. I take it to bed, chocolate at hand,
and *read* it a couple times before I ever run it. Most of the stuff,
hardware-intense deep-embedded stuff, runs first-time.

Of course, I'd never program an accounting application, or anything on
a PC, in assembly.

Ignoring everything except the actual XMAC function and its equivalent,
there are 6 lines (*including* braces) where something is executed in
the C version. (Some of the braces could be removed, but this is the
style I like; others have only syntactical use).

Comparing this to 15 lines (17 if I should be including the OKAY group)
where something can go wrong in the assembler version - how can it
possibly be quicker to develop and test the latter?


You assume that fewer "lines" correlates to fewer errors. That doesn't
make sense to me. It seems to me that clean, visible, *carefully
thought-out* logic will have the fewest errors. *Adding* lines will
often make the flow clearer and safer. I type very slowly, which is
another reason my code has few bugs. *Thinking* about what you're
doing makes it more reliable, as compared to touch-typing hairy code
at blinding speeds. Commenting my code makes me think about it; I
review it on the spot, then again as I proofread it.

Since most programmers spend several times as long debugging their
code as typing it, and typically only find most, not all of the bugs,
clearly they should slow down and think. Commenting is one way to slow
down and think.

I program hard embedded stuff in assembly because I like it, and
because I finish sooner, with far fewer bugs, than the typical C
programmer, and because the result is a beautiful document that I can
come back to years later and understand immediately without having to
"decode" it.

They don't call programs "code" by accident.
Possibly you're one of the few programmers who are just more productive
than the average - there's a measured difference in productivity of
something like 10x(?) between the worst and the best (I think in
Peopleware, by Tom DeMarco)

Well, one of the reasons I'm a productive programmer is because I'm an
engineer, not a programmer.

John
 
R

Rich Grise

Jan 1, 1970
0
Well, whenever the budget permitted it. Sometimes, we were
forced to use toenail clippings...

Bob M.

You had toenail clippers?

;-)
Rich
 
Top