[Coco] Linville's ramblings on assembly vs machine code

Dave Philipsen dave at davebiz.com
Mon Jul 10 02:20:05 EDT 2017


Ok, so the list seems rather quiet so I'll try to stir the pot a bit 
here.  On the CoCo Crew Podcast John Linville rambled on for about nine 
minutes telling us how machine code is essentially the same as assembler 
and there's no reason to even try to learn it as it's simply a different 
(and more difficult) way of 'saying' the same thing.  His reference was 
to a question posed by John Mark Mobley on 5/31 at 11:52 AM.

I am in agreement with part of what John said.  That is, that machine 
code and assembler are essentially just different ways of 'saying' the 
same thing.  However, John went on to say that you're already cool if 
you know how to code in assembler and you don't have to show how macho 
you are by entering in the raw data which is representative of the 
assembler mnemonics.

First, let's look at John Mark's original question: How do you practice 
simple machine code on a CoCo.  (?) This is just to teach the basics of 
machine code as an introduction to assembly. What steps should one 
follow to practise machine code. (?)  Note that John Mark mentioned that 
this was just to teach the 'basics' of machine code as an 'introduction' 
to assembly.  It's not a full blown course on how to write a huge piece 
of code entirely in machine language.

In my personal opinion, I can see why an instructor would want his 
students to at least get a taste of how entering raw numerical data as 
'machine code' actually works.  It's certainly not necessary to memorize 
all of the hex (or octal or binary or decimal) codes that represent all 
of the processor opcodes with all of their different addressing modes.  
That would be ridiculous (and difficult)!  But, seeing how machine code 
differs from assembler gives you an eye into how the CPU actually 
works.  Here are a couple of examples:

I was talking with someone once about pushing and pulling registers 
to/from the stack on the 6809.  He had a concern about how one 
particular disassembler represented the order in which a list of 
registers would be pushed or pulled.  From the point of view of someone 
who worked purely with assembly mnemonics and never even bothered to 
look at the machine codes that had been assembled, this might be a valid 
question.  Does it matter how you order the registers when you push or 
pull them? (i.e. is pshs  a,b,x,y different than pshs y,x,b,a ?)
If when you learned assembler you at least got a taste of how it relates 
to machine code you would know right away that it matters not because 
each of the registers to be pushed or pulled is represented by a single 
bit in a post code byte that follows the opcode.  The processor will 
always push or pull the registers in the same order regardless of how 
you write it in assembler.  So to answer the question: no, pshs a,b,x,y 
is not any different than pshs y,x,b,a.

Another example might be when using the load effective address 
instruction.  Why is the construction of leax 1,x any different than 
leax 100,x?  Again, a person who is only familiar with the assembler 
mnemonics would not necessarily understand that the former needs one 
post byte while the latter needs two.

The same might be true with bhi and lbhi.  A person not familiar with 
the machine codes might wonder why there is even a differentiation 
between branches and long branches.  Why not just write them all as long 
branches?  A good book on assembly language (like Lance Leventhal's) 
will explain why.  And when it explains why, you are actually delving 
into machine language.  Now you understand why long and short branches 
are necessary and why stack order is not important.  In fact Leventhal's 
book could have been entitled '6809 Assembler Language Programming with 
machine code examples'!

So, yes, it doesn't make much sense to 'learn' machine language or code 
with it.  But, it makes a lot of sense to understand it fundamentally.  
This becomes even more necessary when you are doing any of the 
following: 1) programming in an environment where the amount of memory 
is severely limited, 2) programming something that can only be 
accomplished in assembler/machine code because of timing and/or speed 
issues, and 3) working in a target environment where an assembler is not 
available.  The last issue, number 3, may be when you use a machine to 
assemble code that ends up in an embedded device that has neither a mass 
storage device nor enough memory to run an assembler.

Many of us have written assembler code that runs on our CoCos, 
Commodores, Apples, etc. but have never written the same type of code 
(6809, 6502, Z80, etc.) to run on another target with limited 
resources.  Those of us who have will tell you that it is very 
beneficial to at least have an understanding of machine code and how it 
works.

Most of us, however, know the difference between the word "can't" and 
the expression "can not" (or cannot).  Even though they all mean the 
same thing I think that you would consider yourself better educated for 
knowing the difference.

Dave



More information about the Coco mailing list