PASM is universal?
lardom
Posts: 1,659
After a partially browsing a tutorial on PASM a couple thoughts occurred to me: If assembly is one level above machine language, and I assume machine language is the starting point for all computer languages, then the only difference between PASM and any other assembly language is mnemonics. BIOS must be assembly. C/C++ is probably a high level language like "Spin" which became a standard programming language. I don't yet understand the significance of 'object oriented'. Am I still pretty far off?
Comments
Have a look at the Wikipedia's article on "object oriented" for more detail.
Note that the machine instructions available, and their encoding, differ from chip to chip, so you can't use 80386 assembly language for a Propeller, and vice versa! It's not just that the mnemonics are different, but the instructions that the machine understands are different.
Typically assembly language adds a bit of convenience (e.g. you can use labels instead of numbers to refer to memory locations, and the assembler does some calculations for you), so in a sense it's higher level than machine language, but only just.
C is slightly higher level still, because there's now a compiler that translates your C statements into machine language, and the mapping from C to machine language depends on the compiler -- a good compiler will produce very compact, "natural" code, but a weaker compiler will produce more inefficent code. The code above might be written in C something like: A compiler might turn it into PASM code that looks like: for a not so great compiler, and for a better one. (Actually I used GCC for both of these examples, but just improved the optimization level for the second one.)
Spin is a bit of a special case because AFAIK there is no compiler to translate Spin to PASM; rather the procedure is to translate Spin to "bytecodes" which are then interpreted by a program that runs in a COG. These bytecodes are designed to minimize the size of the program. The COG program reads the spin byte codes out of hub memory and then performs actions based on them. If it sees one number it will add some COG registers together, if it sees another it will subtract, and so on. This is very much like what the Propeller hardware does for machine instructions, but instead of each instruction taking 4 bytes of memory the Spin bytecodes can be variable sized in length (many of them just 1 byte) and can do more complicated things than the Propeller machine instructions. So the Spin bytecode program takes up much less memory than an equivalent machine language (or PASM) program. The Spin bytecodes can also be placed in hub memory (of which there is 32K) instead of COG memory (of which there is only 2K).
And on the Propeller the small size of the internal COG memory has led to a kind of hybrid called LMM PASM (LMM stands for "Large Memory Model") where there is a very simple "bytecode" interpreter that reads machine instructions from hub ram and then executes them in COG memory. This is much faster than the Spin interpreter, since there is virtually no decoding of the instructions necessary, but the tradeoff is that the code is much bigger. Many high level languages for the Propeller actually use this mode of operation (including most C compilers).
Eric
Some CPUs use a load operate store model that contains registers that are addressed as such apart from memory locations. Others use a memory to memory design. That is probably the biggest variance I've seen.
If you've done assembly language on one CPU, mapping what you do to another one is a matter of understanding the model, load store vs memory direct, as much as it is understanding the various operations provided.
So it's not really universal, in that programs generally must be rewritten, but it is in terms of the overall approach, IMHO.
@Mike Green, I bookmarked the article.
@Potato head, you authored the tutorial I referred to. I have a lot of studying to do.
On a Prop, the core CPU design is a memory to memory design. It doesn't make use of registers addressed apart from memory. It also has conditional execution and flags to determine whether or not a given operation changes memory or the flags: zero and carry.
On other CPUs, there are often registers, which are addressable apart from memory! They may or may not be conditionally executed too.
eg:
mov destination, source -- moves a number contained in the storage at the source address to the destination storage address (prop)
vs
ld r2, source -- moves a number contained in storage at the source address to the register addressed as "r2"
LDA source -- moves a number contained in storage at the source address to register "A".
All three of those move a number from one addressable place to another. That's a universal operation in assembly language. The actual places one would move the number, do vary according to how that processor works.
On load store processors, one needs to pick the number up, put it into a working register, then put it down in to storage RAM again, to accomplish what a memory to memory design does with one instruction. So then, after performing the loads above, the load store designs would require this:
mv destination, r2 -- moves the number contained in register "r2" to the storage addressed at destination
STA destination -- moves the number in register A to the storage addressed at destination
This is probably the most important bit of understanding of assembly language. One must understand the hardware in high detail to write effective programs. A higher level language like C doesn't have that same requirement. It can be done in C, but one doesn't have to do it, and in fact, not doing that is desirable because it then makes it considerably easier to use the same program on different CPUs.
**I made up basic mnemonics to highlight differences in CPUs and the implications of those differences on what their assembly language might look like.
The first thing one does when considering an assembly language program on a given CPU, is look at the programming model and hardware data sheet(s). All computers really only do a few things! They add numbers, operate on them, and move them around.
What those numbers do is largely dependent on the hardware features of the CPU and connected devices. Storing a number into RAM is just storing a number. Store that same number in some address being watched by an additional device, and that same number might put a character on the screen, emit a sound or trigger current to flow to an LED.
Re: Tutorial. Well cool! Let's hope it gets you over the hump! That one is very basic, and it does contain some of the core things important to me when I got my head wrapped around the basic assembly language concepts. Ask lots of questions, keep your goals very simple, like blinking that light, or making some sound (rapidly blinking light can be clicks on a speaker), and don't stop asking them. When it clicks, you will know, and you are off to doing greater things.