26

I'm a student, fresh into programming and loving it, from Java to C++ and down to C. I moved backwards to the barebones and thought to go further down to Assembly.

But, to my surprise, a lot of people said it's not as fast as C and there is no use. They suggested learning either how to program a kernel or writing a C compiler. My dream is to learn to program in binary (machine code) or maybe program bare metal (program micro-controller physically) or write bios or boot loaders or something of that nature.

The only possible thing I heard after so much research is that a hex editor is the closest thing to machine language I could find in this age and era. Are there other things I'm unaware of? Are there any resources to learn to program in machine code? Preferably on a 8-bit micro-controller/microprocessor.

This question is similar to mine, but I'm interested in practical learning first and then understanding the theory.

AceofSpades
  • 605
  • 1
  • 7
  • 12
  • 2
    What *exactly* is the problem here? If you're asking if it's possible to code in machine code then the answer is probably "yes". If you're asking for tutorials then a) make it clear that's what your question is, but b) it's not a constructive question. – ChrisF Dec 20 '11 at 09:17
  • Thanks, changed the question and added the word "tutorial." is there anything else I need to change/edit/delete? I thought everything is needed but it could be the proper way I need to present it in. Again, thank you :) – AceofSpades Dec 20 '11 at 09:26
  • 6
    Is C not bere metal enough? – Tom Squires Dec 20 '11 at 09:45
  • @TomSquires I understand your reasoning but I want to see if I could go one step further.. I'm just anxious and need to learn. Appreciate your reply :) – AceofSpades Dec 20 '11 at 09:51
  • 1
    Here is one that looks good http://maven.smith.edu/~thiebaut/ArtOfAssembly/artofasm.html I havent personally used it, even the microcontroller stuff i have done uses a C variant. – Tom Squires Dec 20 '11 at 09:59
  • 6
    I `program bare metal` every time I kick my server box. Works wonders! – yannis Dec 20 '11 at 10:50
  • 1
    Outdated, but possibly interesting: [Intel Architecure Programming and Information](http://intel80386.com/) – yannis Dec 20 '11 at 10:58
  • 7
    Ever considered going even further down? Hack your own CPU: http://opencores.org/ – SK-logic Dec 20 '11 at 12:03
  • 3
    @SK-logic, yeah, the machine code programming would get insufferable after about 1 hour. You're right, a better and more productive idea is to get down to the CPU implementation. There are also virtual versions of the 6502 (http://www.visual6502.org) as well as folks who have or aspire to construct CPU's using modern discrete logic (http://www.bradrodriguez.com/papers/piscedu2.htm) – Angelo Dec 20 '11 at 12:50
  • 1
    If assembly doesn't satiate your low-level curiousity then try looking into electronics. It sort of became a hobby of mine, starting with my desire to reverse engineer my old garage door opener. This helps you understand the role that various electronic components and microcontrollers play. From there you can simply view the computer as an enormously complex symphony of electronic components in perfect (and suprisingly not so perfect) harmony with each other. – maple_shaft Dec 20 '11 at 14:28
  • 1
    You should start by building a [magic switch](http://catb.org/jargon/html/magic-story.html). – Dan Ray Dec 20 '11 at 15:02
  • @YannisRizos thanks for the Edit and refference. – AceofSpades Dec 20 '11 at 18:16
  • @SK-logic thank you, this looks interesting yet more leaning towards hardware. But I think you are right It sounds like the perfect low level. – AceofSpades Dec 20 '11 at 18:20
  • @maple_shaft I'm doing an electrical engineering and love those capacitors, resistors,circuits. Thanks for the comment :D – AceofSpades Dec 20 '11 at 18:23
  • @DanRay a switch connected to ground inside motherboard? Hmmm... Nice. Thanks for sharing :) – AceofSpades Dec 20 '11 at 18:29
  • I was reading this other thread and I guess I stumble upon this: http://programmers.stackexchange.com/a/82573/43388 anything of that nature I could find a tutorial on? But, I need to learn assembly first to make the transition easier. – AceofSpades Dec 20 '11 at 18:39
  • Added +1 to all the deserving answers/comments. – AceofSpades Dec 20 '11 at 19:08
  • @AceofSpades: Did you know you can accept the best answer? Just press the check next to the answer. – Dynamic Dec 21 '11 at 00:09
  • @perl.j yeah, I think I just wanted to wait another day to see if I get any other response.. – AceofSpades Dec 21 '11 at 01:19
  • 1
    If at all possible, find an 8-bit processor you like and play with that. The z80 is quite powerful but still manageable. The 6502 is different in using index registers for many things - making for a different style. –  Sep 06 '12 at 07:56
  • You could design or write a Console Emulator such as an NES, Sega, SNES, PS2 etc. emulator that loads rom files. They are pretty bare bones! – Francis Cugler Jun 26 '17 at 04:21
  • You could purchase a TI83-84 graphing calculator and use its program interface to write programs. That's pretty bare bones too. – Francis Cugler Jun 26 '17 at 04:23

9 Answers9

27

People don't program in machine code (unless they are masochistic). They use (or develop) tools to generate machine code (compiler or assembler, including cross-development tools), or perhaps libraries generating machine code (LLVM, libjit, GNU lightning, ....). So resources about machine code generation, compilation, optimizers, and micro-architectures are also relevant.

And very often, a good optimizing compiler generates better machine code than you could do. You'll probably don't be able to write a 200 line assembler code better than a good optimizer.

If you want to understand machine code, learn assembly first. It is very close to machine code. Use it wisely, only for things you cannot code in C (or in some higher-level language, like Ocaml, Haskell, Common Lisp, Scala). A good way is often to use asm instructions (notably GCC extended assembly feature) inside a C function. Reading the assembly code (generated by gcc -S -O2 -fverbose-asm) can also be helpful.

The Linux Assembly HowTo is a good thing to read.

Current processor's instruction set architecture (i.e. the set of instructions understood by the chip) are quite complex. Common ones are x86 (a typical PC in 32 bits mode), X86-64 (a desktop PC in 64 bits mode), ARM (smartphones, ...), PowerPC etc. They are all quite complex (because of historical and economical reasons). Perhaps learning first an hypothetical instruction set like e.g. Knuth's MMIX is simpler.

Maxpm
  • 3,146
  • 1
  • 25
  • 34
Basile Starynkevitch
  • 32,434
  • 6
  • 84
  • 125
  • 8
    "People don't program in C (...). They use modern languages, perhaps with C backend" – Abyx Dec 20 '11 at 10:31
  • I definitely agree. And my current work project (MELT, see http://gcc-melt.org/) is a DSL translated to C. – Basile Starynkevitch Dec 20 '11 at 11:00
  • I added some references to ISAs – Basile Starynkevitch Dec 20 '11 at 14:26
  • 6
    What about those who want to create and assembler? There are reasons to learn machine code, though they aren't that common. – Jetti Dec 20 '11 at 15:06
  • I would say that it is learning an instruction set architecture (using the assembly mnemonics). You rarely learn explicitly the exact encoding of instruction (e.g. that NOP is 0x90). You many need to know it when writing an assembler or a machine code generator. (Likewise, you rarely need to learn by heart the UTF8 encoding of Unicode). – Basile Starynkevitch Dec 20 '11 at 15:08
  • @BasileStarynkevitch +1 for added paragraph :) I know I might never use them but they'll help understand the much more complex coding. I can always trace back the problem if I ever needed :) – AceofSpades Dec 20 '11 at 18:59
  • I _do_ program in assembler in my free time, but for Z80, which is a relatively simple processor. I find it funny and I don't consider myself a masochistic. – Konamiman Sep 06 '12 at 08:56
  • @Konamiman Assembly language is not the same as machine code :) It's one (admittedly very small) step above it. – Andres F. Sep 06 '12 at 14:41
  • @BasileStarynkevitch Untrue. Exploitation software is often written in assembly (which is clearly what he meant) – Griffin Mar 31 '13 at 22:00
  • 2
    Answers like these are why I hate SO lmao. This didn't answer the question, this just mocked the OP for daring to ask how to do something that this person didn't think was worth it. I think the OP should decide what's worth their investigation. – Sophie Coyne Dec 15 '19 at 00:51
  • 2
    @RobbieCoyne I entirely agree,I aboslute HATE it when someone asks "how can I do this" and the answer is "thats stupid. Don't do that" -- even if there is plenty of valid reason for doing it, where else are we supposed to ask but here? – B''H Bi'ezras -- Boruch Hashem Apr 27 '20 at 11:55
13

As was stated previously Learn Assembly.

An assembly language is a low-level programming language for computers, microprocessors, microcontrollers, and other programmable devices. It implements a symbolic representation of the machine codes and other constants needed to program a given CPU architecture.

So Assembly is a symbolic representation of machine code.

You may now be asking "Ok, so how do I learn all of that?" I am so glad you asked:

  1. Understand what it is. It is very low-level and will give you a very in-depth understanding of a computer. You might want to start with Wikipedia and then read this short passage.
  2. Learn it! Best reads are probably The Art of Assembly Language and Assembly Language Step-by-Step: Programming with Linux
  3. Get coding!
Dynamic
  • 5,746
  • 9
  • 45
  • 73
  • I was reading this other thread and I guess I stumble upon this: http://programmers.stackexchange.com/a/82573/43388 anything of that nature I could find a tutorial on? But, I need to learn assembly first to make the transition easier. – AceofSpades Dec 20 '11 at 18:41
  • 1
    Thanks, I guess I need to learn assembly on popular demand. +1 – AceofSpades Dec 20 '11 at 18:55
  • 1
    But the question doesn't mention if the questioneer learned assembly yet or not. What if one DOES know assembly, how can one go one step further to create ones own assembler???? – B''H Bi'ezras -- Boruch Hashem Apr 27 '20 at 11:56
8

I strongly suggest that you reconsider your goal and here's why:

I first learned 6502 Assembly Language on the BBC Microcomputer (Model B, 32K). It had an awesome BASIC implementation that included a macro assembler. We had them at school so I wrote all sorts of mischievous programs that would do things like direct screen buffer manipulation to make a Lemming walk across each screen, around the room (they were networked) if the machines hadn't been used for 10 minutes. It resulted in fits of giggles among my Year 7 friends.

When I got a Commodore 64 at home, I learned that it had a 6510 CPU which also ran 6502 assembly language but with some interesting extras. I had to buy an assembler (came on a cartridge) and invoke the programs via BASIC. With grand visions of writing a best-selling game, I eventually managed to create several demos that bit-twiddled video display hardware registers on interrupt to do interesting colour bar effects that animated to funky chip music. Impressive, but not that useful.

I then got an Acorn Archimedes A310 which had an ARM2 CPU so I used the same awesome BASIC implementation with built-in macro assembler as the BBC Micro (same heritage). I managed to put together a couple of games which an arty friend provided graphics for, plus some sinusoid-based trippy demos. Both of these were hard work to program and bad code could take down the machine (accidentally trip hardware reset register, etc), losing everything if I hadn't saved (to floppy!).

At University I was introduced to C++ and thus C. I was able to use it to program Sun/Solaris and some other large mainframe computers. I have no idea what CPU architectures these machines ran on - I never needed to use assembler or read machine code as the C++ tools gave me the power I needed to produce professional applications.

After Uni, I worked on Windows and several flavours of Unix. C and C++ worked on all these machines and eventually Java did too.

I then worked on Windows and Dreamcast using C++ with DirectX with comprehensive tool chain for debugging.

I then took a job working with ARM-based chipsets for Smart TVs (in 2000). Although my experience with ARM2 may have been relevant here, the job was C based. I found that all the poking about with hardware that I'd done on the Archimedes could also be done in C using straightforward bit-twiddling operations. Part of my role was to migrate the code base to Windows, Playstation 2, Linux, other TV and mobile chipsets. All of these platforms were available with both a C compiler (often GCC) and some level of API to write to the underlying machine - the embedded world is rarely a kernel O/S. I didn't ever need to know the full machine code for any particular platform beyond writing a boot loader and mini-BIOS, both of which jumped into C code at the first available opportunity (after setting up trap vectors, ensuring endian-ness and instruction-mode and establishing a stack).

The next job was working with C++, C# and JavaScript on Windows. No machine code.

The current job is working with C++, JavaScript, Python, LUA, HTML and other languages on various platforms. I've no idea what machine code these platforms run, nor do I need to know - the compiler translates our code into whatever it needs to be. If it crashes, I catch the error in a debugger or through runtime diagnostics (exceptions, signals, etc).

For fun, I develop iOS applications on the little spare time I have at home. It uses Objective-C and an API that works across multiple chipsets. Apparently they're ARM-based, but I've never seen any machine code in my development.

While its' a fascinating exercise to learn assembly language, there are now much higher-level tools and languages that allow you to be an order-of-magnitude (or two) more productive.

The number of job opportunities available to an amazing assembly language/machine code programmer are miniscule compared to something like JavaScript, Java, C#, C++ or ObjC.

I'd advise you make this a hobby/side-interest rather than a main goal.

JBRWilkinson
  • 6,759
  • 29
  • 36
  • 7
    It is a hobby. I'm interested in how things work and learn to manipulate them at very basic level if possible. +1 – AceofSpades Jan 13 '12 at 01:36
6

My suggestion? Learn MIPS and learn how to build a (simple) MIPS processor. It's actually easier than it seems.

The advantage of MIPS over some of the other architectures is simplicity. You won't get caught up in a ton of little details, but you will still learn all of the big ideas you need to write code in other architectures.

Coincidentally, this was the final project for my (third) intro CS class. If you want, you can read the assignment and browse through the lectures as videos or slides.

Among other things, we did cover how MIPS code gets turned into binary; we even had to decode some (very simple) machine code on the exams.

Even if you don't want to cover everything, most of the lectures were given by one of the students' favorite lecturers and are fun to watch by themselves.

Tikhon Jelvis
  • 5,206
  • 1
  • 24
  • 20
6

I'm a student, fresh into programming and loving it, from Java to C++ and down to C. I moved backwards to the barebones and thought to go further down to Assembly.

Excellent path to take. My jump (fall?) from C to Assembly and lower was a university course Computer Organization and Design, based on the book by the same name.

Highly recommend this book for the first chapters on basic MIPS assembly, all the way through pipelining and memory architecture. Even better would be to take a course around the same theme, or find some lectures online.

Also see the MARS MIPS Simulator to get your hands dirty writing assembly.

Matt Stephenson
  • 279
  • 1
  • 3
4

If you want to understand how the machine works completely, why don't you go the lowest level possible and build your way up to where you are (e.g., C,C++)?

By that I mean: why don't you build your own 4-bit adder with transistors on a circuit (just Google it if you are looking for instructions/tutorial)?

After that build a small computer with some RAM, and then start learning Assembly and write a program or two with it.

Daniel Scocco
  • 5,832
  • 9
  • 39
  • 47
  • If the original poster build a computer from scratch, he will have to *define* (not just learn) his own assembly. – Basile Starynkevitch Dec 20 '11 at 14:49
  • @daniels I understand the reasoning by learning adding from bits which is true low level. +1 – AceofSpades Dec 20 '11 at 18:50
  • An alternative to building a computer from scratch could be learning some old processor (and its assembly language) like the Z80 or 6502 that is still simple enough to be understood. I guess there are even emulators that you can play with. – Giorgio Sep 06 '12 at 08:20
  • @AceofSpades A great way to easily build CPUs and CPU components (eg. an adder) is with redstone in Minecraft, I would recommend that. I've started working on some simple machines in Minecraft, and it has highly boosted my understanding of the theory and logic behind computers. – Name Feb 15 '13 at 00:26
1

I have an instruction set that was made for this, a simulator, and some tutorials on the basics one instruction or concept per lesson. Just type the program, run it then learn what it does, move on to the next lesson.

http://www.github.com/dwelch67/lsasim

I also have simulators for a few mainstream instruction sets as well. Any or all of which are good for using to learn asm (if you really feel you have to learn x86, learn it last, and use a simulator like the one I have forked, 8088/86 first then move forward). Learning against a simulator has pros and cons, one major pro, esp when starting out, is you dont crash anything and you have great visibility. Jumping in head first into an embedded platform, microcontroller, etc to learn a new instruction set you have to overcome the hurdles of not being able to see what is going on, leading to a long list of ways to fail...

old_timer
  • 969
  • 5
  • 8
1

Code by Charles Petzold is a very good introduction to the subject and describes the process of building a computer including how to construct adders, counters and RAM arrays and introduces machine code and assembly language and their relation to higher level languages. It's also a great read on the history of computing.

And I've just read this question on electronics.stackexchange which could be of use too

br3w5
  • 719
  • 2
  • 6
  • 12
-2

For machine language study and programming
MASM software may be used.

For MASM, the following link may be used.

http://en.wikipedia.org/wiki/Microsoft_Macro_Assembler
http://www.microsoft.com/en-us/download/details.aspx?id=12654

gnat
  • 21,442
  • 29
  • 112
  • 288