Page 1 of 1

How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 6:31 am
by Dewah77
Well almost everywhere I'm supposed to know everything about registers etc before asking something, but unfortunately I have no clue about those. What am I supposed to do here :oops:

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 7:58 am
by Octocontrabass
Google is a good first step. If you want a tutorial, there are plenty of those around (but be aware most OSdev-related tutorials are full of nasty bugs). If you'd rather get some more hands-on knowledge, you could find examples of code written in assembly and try to figure out how it works, or try disassembling/debugging simple programs to see how they work.

The x86 architecture manuals (from both Intel and AMD) are valuable references. You'll want to keep a copy of at least one of them handy.

OS development requires some pretty in-depth knowledge about the CPU and hardware, far more than what a normal application developer would need to know. Fortunately, most of what you need to know as an application developer can be applied to OS development.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 9:12 am
by Solar
The Assembly page right there in our Wiki has a couple of good pointers at the end. Personally I'd recommend "The Art of Assembly Language Programming", which really plunges the depths of how the x86 dialect came to be.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 9:41 am
by SpyderTL
You may want to start off using assembly to write a MS-DOS program. This will allow you to use MS-DOS and the BIOS to make it easy to read events from the keyboard and write characters to the screen. If you are trying to learn ASM, you probably don't also want to learn about frame buffers and keyboard controllers at the same time.

It's a lot easier to write a "Hello, World!" program in MS-DOS than it would be to write one with no OS running at all.

Basically, the program that you write is converted (compiled) into byte codes (i.e. a byte array). That byte array is loaded into memory by something (usually the OS), then the CPU starts at the beginning of that byte array, and executes each instruction one at a time.

It's helpful to remember that the CPU can only really do a few things, on it's own. It can copy one register to another, it can copy a register from and to a memory address, it can copy a register from and to an I/O port, and it can add, subtract, multiply and divide one register by another. Everything else that your PC does requires some external component on the motherboard, and the only way the CPU can communicate with the motherboard is through reading and writing to memory addresses or I/O ports. The motherboard actually decides what addresses and ports are connected to which devices.

Hopefully, this will help you get started. Let us know if you have any specific questions about the hardware or BIOS functions.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 11:25 am
by BenLunt
There is a free and easy to use assembler found at http://www.fysnet.net/newbasic.htm which includes many examples and an IDE.

This is the same assembler that is used to assemble the source code found in Volume 1: The System Core which shows you how to make a minimal operating system kernel in assembly.

Both the assembler and the book are fully supported by the author either by email or this forum.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 12:48 pm
by Octocontrabass
SpyderTL wrote:MS-DOS and the BIOS
Real mode is a terrible introduction to the x86 architecture. Most OS developers have no reason to bother with real mode anyway, since it's not very relevant outside of bootloader development. It's much better to start with an OS that runs in protected or long mode; Windows and Linux are both reasonable choices.

You can't use the BIOS outside of real mode, so there's no reason to bother with that either, outside of bootloader development.
BenLunt wrote:There is a free and easy to use assembler found at
This assembler is very DOS-centric. For learning x86 assembly on a modern OS, it's much better to use an assembler that natively produces PE (Windows) or ELF (Linux) object files. YASM and gas both meet this requirement, and both are cross-platform, so you can use whichever you prefer. Fair warning though, gas uses AT&T syntax by default.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 1:35 pm
by BenLunt
Octocontrabass wrote:
BenLunt wrote:There is a free and easy to use assembler found at
This assembler is very DOS-centric. For learning x86 assembly on a modern OS, it's much better to use an assembler that natively produces PE (Windows) or ELF (Linux) object files. YASM and gas both meet this requirement, and both are cross-platform, so you can use whichever you prefer. Fair warning though, gas uses AT&T syntax by default.
You are correct, this assembler is made for DOS, but only to be executed from DOS, not DOS specific output. I use NBASM to create binary files. NBASM has been written to specifically cater for my needs in OS development, as so does the C compiler that is on that same page. Alex, who frequents this forum wrote that C compiler and I ported it to my assembler, giving it a few additions, mainly to allow far address access.

My loader file is 90% C (with the 10% being inline assembly) all compiled to assembly ready for the NBASM assembler. It is a mix of 16-bit and 32-bit assembly output all indicated with a simple #pragma line.

Again, don't get me wrong, my assembler and C compiler (ported from Alex's) is not the next greatest assembler and compiler. It is simply catered to my needs for OS development only, yet I figured that others might benefit from it, so I have released it.

As for some of the additions I have made to the compiler, and please note are absolutely *not* ANSI/C99/etc. compatible, are the addition of the FARx type specifiers. For example:

Code: Select all

  bit8u farF *a_far_ptr;
will specify to the compiler to add the "fs:" segment override to any access to "a_far_ptr".

Code: Select all

  mov    ebx,[a_far_ptr]
  mov    al,fs:[ebx]
Then all I have to do is while using inline assembly, set up the FS segment register/selector and all access to "a_far_ptr" will be from that segment/selector region.

Alex has done a wonderful job with this compiler and I am sure he has made many improvements to it since the last time I have looked, but I have made changes to it to cater to my needs. Please keep that in mind, I wrote it to cater to my needs. period.

If anyone uses my C compiler (NBC) and/or assembler (NBASM) for their OS development and has any questions on how to use it, please send me an email or better yet, post here to this forum. I am glad to help people learn.

Thanks,
Ben

P.S. I don't mean to start a war here, or offend anyone, but in my opinion, you are defeating the purpose of OS development if you use a compiler or assembler that creates an output file already specific to another OS, for example, PE files. In my opinion, do not write your OS to load PE files. This relies on the fact that you are catering your OS to rely on the format of another OS. Create your own format. Just my humble opinion though.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 1:54 pm
by Octocontrabass
BenLunt wrote:P.S. I don't mean to start a war here, or offend anyone, but in my opinion, you are defeating the purpose of OS development if you use a compiler or assembler that creates an output file already specific to another OS, for example, PE files.
PE files are not specific to one OS. :wink: Besides, the point is learning assembly, and jumping straight into OS development is a terrible way to learn assembly. We should save the object file format discussion for a thread about object file formats.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 2:51 pm
by BenLunt
Octocontrabass wrote:
BenLunt wrote:P.S. I don't mean to start a war here, or offend anyone, but in my opinion, you are defeating the purpose of OS development if you use a compiler or assembler that creates an output file already specific to another OS, for example, PE files.
PE files are not specific to one OS. :wink: Besides, the point is learning assembly, and jumping straight into OS development is a terrible way to learn assembly. We should save the object file format discussion for a thread about object file formats.
I Agree. Though I am just suggesting to the newbie to venture out and create anew.

Getting back to the other, I just wanted to point out that I have a good example of the "farX" pointer stuff from my compiler at:
http://www.fysnet.net/nbc.htm

Thanks,
Ben

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 4:12 pm
by SpyderTL
Octocontrabass wrote:Most OS developers have no reason to bother with real mode anyway, since it's not very relevant outside of bootloader development. It's much better to start with an OS that runs in protected or long mode; Windows and Linux are both reasonable choices.
I considered mentioning Windows and Linux, but if you are just getting started with ASM, I wouldn't recommend jumping directly into PE/ELF files, sections, DLLs, and various calling conventions, just so that you can read keyboard press events, or write characters to the screen.

Re: How do I start learning assembly for making an OS

Posted: Wed Aug 10, 2016 4:58 pm
by tsdnz
Hi, when I first started out, at the age of 8, I had to use hexadecimal, putting these into memory and running it, wow did it take ages.

Much, much later.....
I found that using Microsoft Visual Studio or Delphi is much easier.

Visual Studio has a debugger for assembly, simply create a c++ program, view the assembly output and you can debug on instruction at a time.
From there you can view the registers and see what the instructions do and/or set.

After this you can write your own assembly and also debug it using VS.

Good luck.

Re: How do I start learning assembly for making an OS

Posted: Thu Aug 11, 2016 4:37 am
by Dewah77
Thanks for your help, I'll try to start with an OS and if its too hard I would make some simple program in an OS.
The reason I want to start with an OS is that I shouldnt learn Win32/etc calls to make an OS :D that would do the work for me

Re: How do I start learning assembly for making an OS

Posted: Thu Aug 11, 2016 4:43 pm
by ~
Dewah77 wrote:Thanks for your help, I'll try to start with an OS and if its too hard I would make some simple program in an OS.
The reason I want to start with an OS is that I shouldnt learn Win32/etc calls to make an OS :D that would do the work for me
Stay around this forum and also look at my websites for the projects I've made. I've written several small programs in assembly.

You can start making a graphical GUI for DOS with a shell with Win32 functions in it to manipulate long file names (see it with an ASCII binary hex editor, create, delete, rename, move, copy, paste...). In this way, if you use the existing USBDOS, DOSLFN, FAT and NTFS drivers for DOS, you can avoid actually using Windows if you just want to manipulate your files. Then you can implement file viewers or implement a virtual DOS console in graphics mode. With this you will cover most of the basic functions that you would need as an user (except a web browser, network and other advanced things). With this you already have a lot of work to implement a shell and OS-level functions, plus a graphical shell with full WinAPI and full file management functions (even if it initially cannot execute other programs like an OS) is something that is lacking in the DOS world, but it's something that would simplify again home computing to the simplicity level of DOS and its programs.

The people who made Wolfenstein 3D and other games at ID Software (or any other company or group for that matter) should have implemented such graphical shell for DOS before or during Windows 3.x with full file manager functions and some file viewers, then Windows would be secondary until today (and maybe the capability to invoke other DOS programs from it). It's as if they got confused at the point where they had to implement a GUI, understand 32-bit Protected Mode and properly deal with the drivers for the different devices in that single application (and later clone the DOS and Windows functions with and without using V86). Then Microsoft (and Linux/UNIX in lesser measure) had that idea but nobody else thought about creating a full GUI and file manager.


One thing you must know is that Intel x86 assembly is one of the easiest. It has the mentality of working like a high-level language. It's a very high level assembly actually.

Look at it this way:
- Each instruction of the x86 CPU is a request to perform a concrete task.

- For example, you tell the CPU things like (multiply these registers as numbers with sign -imul-, without sign -mul-, add these numbers -add-, compare these numbers -cmp-, repeat this block of instructions to loop them -we can use call and jmp-, move these bits to the left or right -shr, shl, ror, rol...-, etc.).

- The x86 CPU is profoundly oriented to software, unlike other embedded architectures intended for electronics and automation where programming is more oriented to manipulate I/O pins and even raw digital or analogical signals.

Re: How do I start learning assembly for making an OS

Posted: Thu Aug 11, 2016 5:52 pm
by Roman
I'd disagree. x86 does not have arbitrary operation destinations, but other architectures have them, for example, ARM and PowerPC, it also lacks more registers (x86-64 solves the latter point, though). It can be inconvenient for both programmers and compilers' register allocators. x86 is by nature an ancient CISC design with a lot of legacy stuff, including the monstrous real mode. Complex instuctions are slower than their multiple instruction counterparts, so they are useless unless you need small code size (which is irrelevant these days).

Re: How do I start learning assembly for making an OS

Posted: Thu Aug 11, 2016 6:22 pm
by ~
Small code is vital when it comes to understanding a lot of different sorts of applications and when it comes to write nice assembly library code that can be ported easily to other assemblers and languages. Things would be blissfully simple if companies continued to write drivers for MS-DOS/FreeDOS (they would be so small that it would be very simple to disassemble and understand them, and they could develop standard hardware and standard software for drivning it), starting with SATA drivers (the most needed currently), and then DOS TSR's or Protected Mode interfaces to optionally use drivers from Windows 3.x, Win9x, Windows NT and Linux (and always the specifications and the driver source code to give full control over the machine to the owner who bought it). That's the best thing after creating fully standard PC hardware.

Then somebody could come along and implement a full GUI/file manager for DOS (a true native GUI DOS program) with WinAPI and any other desired libraries to easily replace Windows and simplify everything to the DOS level, even more than Windows 9x, which would be just perfect for lots of people (like anyone who used Geocities).

What makes the x86 so valuable in practice is DOS, and what makes them both so valuable in turn is the exaggerate amount of demos, programs and very simple source code that is surprisingly capable, if we talk about really understanding the PC architecture's hardware and software system.

In that time to make the PCs possible, it had to be simple and standard so everything was tiny. If now it's bigger is solely because of nonstandard hardware. If we make a DOS install with WAV/MP3 players, with BMP/JPEG viewers, with drivers of all kinds, and applications (game emulators, text editors, GUIs, web browsers, compilers, assemblers, system tools, etc...) we can see that it has nearly the size of an extremely small Linux distro, yet its source code is simpler and the programs that DOS has perform more functions than Linux in the same size of Megabytes.

DOS has been more worked on than Linux (at least in the basics and in seeing more milestones intended solely to clean up and simplify the whole code base whereas Linux still needs to see such a milestone on its kernel and most vital libraries), so DOS is an ideal candidate for a bootloader that is also capable of working as an OS that can invoke programs, including the loader for any other OS. So Win9x was right and Windows NT/XP should have kept intact DOS updated as an extremely capable bootloader. At least now we can work on FreeDOS in the same way.

Finally, you can't take DOS out of the PC. DOS and the BIOS are the essence of this architecture. It also came much earlier than Windows or Linux, so everything is also made easier by keeping DOS updated and using the code available from its whole binary and code base. The structure of the DOS is always kept in one way or another, so everything becomes dramatically easier if ported to DOS. If a computer successfully takes the DOS/BIOS, then it's no longer the PC architecture. It's just a random, non-standard, x86-based computer, much like an x86 Mac, but without any important or impressive-in-practice identity to offer to a home computer architecture and home users, programmers, etc... I guess that there must be a DOS/Windows team to make an open source OS based on them. There's already a team working on Linux to cover UNIX. Such open source DOS/Windows team would need to pack absolutely all of the APIs to an open source version of their libraries. If for example a program fails by working with the functions intended for the Windows 3 level, it would cause an exception and use the ones for the Windows 95 level, if it fails it would use the functions for Windows 98, Millenium, NT 4, Windows 2000, Windows XP, Vista, 7, etc... until it either runs out of options and gets terminated/crashed or works well, keeping a cache of pointers to the last functions that worked well, so even a very shaky program could work in such open source version of DOS/Windows if it contains everything in a single-packaged OS (something that no Windows version has ever seen because it has been too scattered through architecture versions instead of doing what I'm talking about).