How easy/hard is assembly?
I actually found assembly a very intuitive, albeit slow way to program. The instruction set is small but powerful and very deliberate.
You have to manage data storage fairly carefully, because you assign specific addresses manually it is very easy to overwrite a variable that you try to access later. There is no warning that this is happening, and it's not always easy to track.
Debugging Assembly code can be a nightmare, I was using a particularly bad IDE, but still. I would suggested small modules and as frequent testing as possible.
Is it worth it really depends on the project. I would not do another lengthy project in Assembly just due to how long I spent debugging the last one.
Last edited by huntedman on 25 Jun 2011, 12:40 am, edited 1 time in total.
User-land assembly is not that much harder than C. If you already have a good understanding of C (complicated pointer structures with multiple levels of indirection, function pointers, the call stack, difference between calling conventions, virtual memory, paging, etc), then you should be able to start writing simple assembly programs that link with libc within a couple hours. If not, then it might take a little more time, but it will be a great way to improve your understanding of C and how computers work at a low level.
Learning how to work in kernel-land will likely be much more of a chore. You need to learn how to handle interrupts, traps, and faults, how to implement virtual memory, how to switch back and forth between security levels, how to interface with the BIOS, how to read and write segmented memory, and the many idiosyncrasies and legacy support crap that is built into the x86 (virtual mode, a20 gate, etc). You will also need to learn some hardware specific memory mapped io schemes and such (like framebuffers). These things tend to be much more platform specific, and the knowledge you gain from implementing a kernel on an x86 will be harder to take with you to another platform (as opposed to user-land code where it is much easier to pick up another instruction set once you understand calling conventions, virtual memory, tests and branching, etc.).
There are a few abstractions that C compilers provide for you that assemblers don't, such as function calls and loops, but otherwise C and assembler are really not that different (a lot of C constructs correspond to a single line of assembly). C is commonly reffed to among embedded systems developers as universal assembler (with RISC platforms this moniker is especially apt). Assemblers provide a lot more abstraction than most people realize, especially when it comes to dereferencing pointers and choosing the right instructions to work with the right size of data (byte, word, dword, etc). It certainly is a lot easier than typing op-codes into a hex editor.
Is it worth it? That depends on your intentions. Like most things, it is useful for some situations and downright painful in others. It tends be good for small low level stuff that is mostly self contained and tightly coupled to specific hardware implementations. An understanding of assembly is also good for debugging and reverse engineering other peoples code. I used to reverse engineer viruses, library implementations, and copy protection schemes for fun, which vastly improved my ability to read and understand other peoples code. That's probably why always end up having to fix the crappy, old, poorly-encapsulated legacy code on my work project (that management doesn't want to spend time rewriting).
Organizing and maintaining a large application is a nightmare in assembly (and C too). I wouldn't dream of starting a really large project without object oriented language features (and hopefully functional features and garbage collection). I have written some fairly large embedded programs in plain old C, and to a large extent my C looks a lot like object-oriented code (with sets of functions grouped together that all work on a structure). You can even get functionality similar to run-time polymorphism with dispatch methods and the like. But when it comes time to refactor the underlying structure of the code to meet new requirements, it always ends up taking much longer in C.
By the way, these days most C compilers can write much faster machine code than you can reasonably write in assembly. When it comes to the x86, any modern compiler will be able to far more effectively optimize your program for speed or size (or balance) than you would be able to do by hand. They can do loop unrolling, function in-lining, moving invariant tests out of loops, eliminating superfluous range checks, and they can do weird things that you would never even think of like casting a signed int to unsigned to avoid one comparison in a range check. And the list goes on. I have not even scratched the surface of all the weird little optimizations compilers do make your code run faster (without sacrificing any readability).
If you are serious about writing an OS, I would try to write most of it in C (that way you can port it to a new platform once the x86 finally dies (I will dance for joy on that day)). You will still learn all about the x86 platform and computers in general.
AngelKnight
Veteran
Joined: 3 May 2011
Age: 49
Gender: Male
Posts: 749
Location: This is not my home; I'm just passing through
I want to program in assembly for making a OS.
Its going to be a project that I can do when I want to do it.
So It would be programmed at my own pace.
How easy is it to program in assembly?
Is it worth it (My personal answer is yes, but some one might think different)?
You might start a bit smaller and pick up on a "research" [1] OS that's been started by someone else.
If you haven't actually had much experience with the CPU architecture you have in mind you may want to see if you can have a finished operating environment in which to work on small things.
By the way you haven't mentioned which architecture. Your questions suggest something that runs on a desktop (so x86 or PPC is most likely, but for all I know you have an Apple 2 or something
[1] Sometimes called "toy" OSes by some; don't be offended by the phrasing when it happens.
Assembly is fascinating to program in. I used to program the 6502 microprocessor on the Commodore 64. On that you could bank out the ROM based operating system and take complete control of the computer including all the interrupts and I/O. I released some commercial software written in assembly at the time. It is not a forgiving language to program in, a bug tends to equate to a crashed computer!
However, the speed of execution of the code is eye-watering fast. Your code needs to be absolutely rigorous and meticulously crafted. It can take a lot of code to achieve a relatively small amount of functionality. So it is good if you can find code modules etc to plug in rather than do everything from scratch.
Take this specific example of complexity: I needed to write code to multiply integers by ten. A little lateral thinking led to this lightning fast code (expressing algebraically) :
Declaring the original number as X (algebraically) then to get 10 (ten) X do this:
1. Shift the bits left three times of X. That gives eight times X. Store the result.
2. Shift the bits left once of X. That give two times X. Store the result.
3. Add the resulting stored integers from 1 and 2 above. This gives X (8 + 2) i.e. ten times X.
There are added complications if you want to handle overflow etc.
Programming in assembly is not quick but I'd recommend it just for the hell of it.
_________________
I've left WP indefinitely.
I agree with mcg... you should probably go with C/C++ instead of coding the whole thing in assembly. It kind of depends on the architecture your targeting though... if you are working with older chips (early x86, 6502, z80, etc) then assembly might be the way to go. The problem with x86 architecture nowadays (>486 or so) is there are just way to many instructions to really use all the op-codes effectively, and if you want your program to run on say a new 64bit processor and an older 32bit processor you can't use all the instructions that are available on the newer processor. This is something compilers are good at doing though... if you tell your compiler to target a 686 processor or something then the compiler will know which instructions to use.
When I code C/C++ I am always sort of 'thinking' in assembly. I frequently have my compiler output assembly (gcc -S) and not object code so I can actually look at the instructions the code generator used. This is where really knowing the keywords of a language can really help you get the most mileage out of the compiler... things like 'const' are really there for the compiler to use and, when you think about it, doesn't really add anything the programmer couldn't do on their own.
The largest assembly program I have written was probably an implementation of reversi for the MIPs architecture. I came in at 21 pages long (it was well commented) and I did start off by writing a C implementation first. It really wasn't that bad to do but maybe not worth it. One thing I do like a bit more about assembly is having a bit more control over how branching/jumping will occur in the program... you can sometimes organize your branches slightly better because as the programmer you know what data your are more likely to expect the program to handle. (Though with branch predictors it is probably not that important anymore)
Assembly programming isn't necessarily hard its just takes a long time can can be hard to debug! If you want to write an OS for the sake of learning assembly/computer organization then go for it. If you want to write an OS for the sake of being functional you might want to look at C/C++ instead.
