We mostly write programme in high level language. So while studying I came across assembly language. So an assembler converts assembly language to machine language and a compiler does the same with high level language. I found assembly language has instructions like move r1 r3 , move a 5 etc. And it is rather hard to study. So why was assembly language created?or was it the one that came first even before high level language? Why am I studying about assemblers in my computer engineering class?
-
15$\begingroup$ Assembler is human-readable machine code, that's why. $\endgroup$– Andrej BauerCommented Jul 18, 2013 at 8:15
-
5$\begingroup$ Because it's important to know how things work when we are close to the hardware. When we write assembly we understand how the computers hardware works and functions on a low-level. The best way for that is assembly language since machine language is tedious and not read-able like assembly. Would you really prefer using a magic box and never looking inside? $\endgroup$– Spencer WieczorekCommented Apr 3, 2014 at 20:04
7 Answers
"So why was assembly language created?"
Assembly language was created as an exact shorthand for machine level coding, so that you wouldn't have to count 0s and 1s all day. It works the same as machine level code: with instructions and operands.
"Which one came first?"
Wikipedia has a good article about the History of Programming Languages
"Why am I studying about assemblers in my computer engineering class?"
Though it's true, you probably won't find yourself writing your next customer's app in assembly, there is still much to gain from learning assembly.
Today, assembly language is used primarily for direct hardware manipulation, access to specialized processor instructions, or to address critical performance issues. Typical uses are device drivers, low-level embedded systems, and real-time systems.
Assembly language is as close to the processor as you can get as a programmer so a well designed algorithm is blazing -- assembly is great for speed optimization. It's all about performance and efficiency. Assembly language gives you complete control over the system's resources. Much like an assembly line, you write code to push single values into registers, deal with memory addresses directly to retrieve values or pointers. (source: codeproject.com)
Why do we need assembly language?
Well, there's actually only one language we will ever need, which is called "machine language" or "machine code". It looks like this:
0010000100100011
This is the only language your computer can speak directly. It is the language a CPU speaks (and technically, different types of CPUs speak different versions). It also sucks to look at and try to understand.
Fortunately, each section of binary corresponds to a particular meaning. It is divided into a number of sections:
0010|0001|0010|0011
operation type source register other source destination register
0010 0001 0010 0011
These values correspond to:
operation type 0010 = addition
source register 0001 = register 1
other source 0010 = register 2
destination register 0011 = register 3
So this operation would add the numbers in registers 1 and 2 and put that value in register 3. If you literally put these values into a CPU and tell it "go", it will add two numbers for you. The operation "subtract" could be a 0011 or something, instead of 0010 here. Whatever value will make the CPU do a subtraction.
So a program could look like this (don't try to understand it, since I made up this particular version of machine code to explain things):
instruction 1: 0010000100100011
instruction 2: 0011000110100100
instruction 3: 0101001100010111
instruction 4: 0010001001100000
Does this suck to read? Definitely. But we need it for the CPU. Well, if every machine code corresponds to a particular action, lets just make a simple "English" shorthand, and then once we understand what the program is doing, convert it into real binary machine code and give it to the CPU to run.
So our original instruction from above could look like:
(meaning) operation type source register other source destination register
(machine code) 0010 0001 0010 0011
("English") add r1 r2 r3
Note that this English version has an exact mapping to machine code. So when we write a line of this "English", we're really just writting friendlier and more understandable machine code.
Well, this is assembly language. That's why it exists, and why it was originally created.
To understand why we need it now, read the above answers, but the key this to understand is this: High level languages do not have a single representation is machine code. E.g. in C, or Python, or whatever:
z = x + y
This sounds just like our addition from above, assuming x
is in register 1, y
is in register 2, and z
should end up in register 3. But what about this line?
z = x * 2 + (y / 6) * p + q - r
Try representing that line in 16 bits of binary and telling a CPU "go". You can't. Machine code has no single operation instruction to perform an addition, subtraction, and whatever else with 4 or 5 variables at once. So it has to be converted to a sequence of machine code first. This is what you do when you "compile" or "interpret" a high level language.
Well, we have programs to do that, so why do we need assembly now? Well say your program is running more slowly than you expect, and you want to know why. Looking at the machine language "output" of this line, it might look like:
1010010010001001
0010001000010000
0110010000100100
0010001011000010
0010100001000001
0100010100000001
0010010101000100
0010101010100000
0000100111000010
Just to get that one line of Python done. So you really want to debug that?!?!?! NO. Rather, you ask your compiler to kindly give you the output in the form you can actually understand easily, which is the assembly language version corresponding exactly to that machine code. Then you can figure out if your compiler is doing something dumb and try to fix it.
(Extra note on @Raphael's advice: You could actually construct CPU's that work with things other than binary codes, like ternary (base 3) or decimal codes, or even ASCII. For practical purposes though, we really have stuck to binary.)
-
2$\begingroup$ In principle, nothing prevents us from building CPUs that work with assembly language directly. ASCII is just an inefficient encoding for this purpose, that's all. $\endgroup$– RaphaelCommented Apr 2, 2014 at 20:49
-
$\begingroup$ Thanks for the addition. I agree, but skipped that for the purposes of understanding assembly's purpose. I'll add a note. $\endgroup$ Commented Apr 3, 2014 at 8:41
-
$\begingroup$ Actually your computer doesn't speak 0000001110010011 directly. It speaks high and low voltages directly. 0000001110010011 is just a convenient way of writing voltages. $\endgroup$ Commented Aug 11, 2021 at 9:29
So why was assembly language created? or was it the one that came first even before high level language?
Yes, assembly was one of the first programming languages which used text as input, as opposed to soldering wires, using plug boards, and/or flipping switches. Each assembly language was created for just one processor or family of processors as the instructions mapped directly to opcodes run by the processor.
Why am I studying about assemblers in my computer engineering class?
If you need to program device drivers or write compilers then understanding how a processor works is invaluable, if not required. The best way to understand this is to write some code in assembly.
If you take a look at how a compiler writes code it is common to see options for calling conventions which without knowing assembly probably can't be understood.
If you have to resolve a bug and the only input you have is a core dump, then you definitely need to know assembly to understand the output which is assembly code and if lucky augmented with higher level statements of a high level language.
Let me add one less practical aspect. This is (probably) not a historic reason but a reason for you, today.
Assembly (compared to high-level languages) is naked. It does not hide anything (that is done in software), and it is simple in the sense that it has a relatively small, fixed set of operations.
This can be helpful for exact algorithm analysis. Semantics and control flow are so simple that counting all operations (or the expected number) can be done by annotating the control flow graph with transition counts (probabilities). Knuth does this in his TAoCP books to great effect, demonstrating some of the most rigorous algorithm analyses there are.
Anecdote: my colleague has learned to read Java Bytecode for exactly this purpose.
There are answers here:
Why assembly language is still needed if we have high level languages offering sophisticated tools? on Stackoverflow
Why Study Assembly language? by Gary L. Burt
All these answers point to:
- Speed/Memory Optimization
- Understanding how the machine works
- So Noob Programmers become Experts
- If you know assembly, you know how to write compilers for your High Lvl language
- etc
-
1$\begingroup$ Do you share all these views? What is your experience? (In particular, the item "So Noob Programmers become Experts" seems outdated by several decades to me.) $\endgroup$– RaphaelCommented Jul 17, 2013 at 10:33
-
-
1$\begingroup$ I am not touchy, I am trying to help you make your answer a good one (it currently is not, as you only link to a few resources, none of which fully answers the question). Including your own thoughts in a comparative manner is a first step to that end. (Note that by relating opinion in an excluding fashion, you assign a value to them; in other words, you have to be able to argue why you value the opinion enough to (re)post is as an answer.) $\endgroup$– RaphaelCommented Jul 17, 2013 at 15:03
-
$\begingroup$ Well my experience is I really hate and struggling with learning assembly languages after just getting used to some high level programming languages. And I know those who are good programmers or know C++/C beforehand can program in ASM pretty well. I didn't think my opinion was valued enough to be posted in my answer so thats why... $\endgroup$– compskiCommented Jul 17, 2013 at 15:27
-
$\begingroup$ Your first link is broken. $\endgroup$ Commented Oct 18, 2019 at 11:52
Assembly = machine code
Some people keep harping on about how assembly language is different from the numeric codes that the CPU understands.
This (whilst true) completely misses the point.
As far as translation goes assembly language and the numeric (binary, hex whatever) are one and the same thing.
Grok it or drop it
If you grok assembly you know how an actual computer works.
grokking assembly involves:
- Learning the instructions and what they mean (duh).
- Understanding what the instruction do, what they don't do and all their side-effects.
- Learning how a CPU processes the instructions
- How the pipeline works.
- What
multiscalar
means - What a CPU core is.
- How the cache works.
- Understanding how to cycle count
- learning the teachings of Agner Fog
- Understanding how compilers generate code and how they fail at times.
- Optimizing well defined and very specific problems.
If you grok assembly you well have a nearly complete picture of how the CPU connected to your keyboard works.
You need to use this knowledge like a brain surgeon uses his scalpel.
Don't need no stinking abstractions
Unless you grok assembly (and thus the CPU on the operating table) you will never be free of the clutches of the abstractions of the RAM machine (or god forbid the Turing machine the horror).
L33t Hax0r 5k1llz
Assembly also helps to you understand how the 133thax0r manages to defeat the protection schemes. (Q: why does ASLR not work? because mov rax,fs:[28h]
breaks it).
The 0.1%
It is not the knowledge of assembly that matters, but knowledge of the machine your working on that matters.
If you want to know the machine, you must understand it and that means speaking the language of the machine.
If you don't then you're stuck with the abstraction.
That's science and that's good, but that's never the complete picture.
It's like learning to speak Xhosa
Unless you aim for guru level, best stick with what you know, those clicks will complicate your life.
Because it's fun.
-
1$\begingroup$ Most frequent use of the word grok in an article that I've ever encountered $\endgroup$– nikenCommented Sep 28, 2017 at 3:21
To date myself, I first learned RPG II using an IBM System 32, and later learned APL on a 370. I was all about size and speed. My mantra was smaller and faster. Assembly is the most compact and fastest language out there. I would make test programs in both C and Assembly. Where C programs would require 100's of Kb, an equivalent Assembly program would often be less that 5 Kb. When studying the output of the C compiler I would find code that would check and recheck parameters make conditional checks for possible errors that were quite often rare and exotic and quite unnecessary, all of which took time, but the biggest memory bloat was passing absolutely everything to and from the stack.
In today's programming environment writing code provides an extra level of security and protection. Being able to read info directly from a piece of hardware that is not accessible to high level languages, allows you to encrypt with Assembly in a way that a program can only be used on that particular machine. For example encrypting a user key using the MAC address of the network interface, and then parking that key on a specific unregistered sector of the hard drive then marking the sector as bad so that other files can't overwrite it. Of course you lose the sector, but what is that? 2048 or 4096 bytes out of billions or trillions?
-
1$\begingroup$ What does "not accessible to high level languages" even mean? $\endgroup$ Commented Jan 26, 2018 at 14:40