ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Welcome to LinuxQuestions.org, a friendly and active Linux Community.

You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!

Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.

If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.

Having a problem logging in? Please visit this page to clear all LQ-related cookies.

Introduction to Linux - A Hands on Guide

This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.

What's a good operating system to use for learning assembly and familiarizing myself with it?

Slackware Linux helped me become familiar with basic command line tools and how to compile source code using GCC:

I made some very basic scripts to make a toolchain, bootstrap my system and compile every program from source code using custom 64-bit optimizations for piledriver CPU (I change CFLAGS settings from Slackware source code DVD on the "SlackBuild" scripts). I used Gentoo since many recommend that for learning but I find Slackware engages me with Linux's inner workings, structure and how it's pieced together (Linux from Scratch I think is similar), and rolling distributions don't seem stable to work on. I refer to Gentoo documentations for speed tips and compiling issues with certain aspects (Gentoo support and documentation is helpful and way out there thankfully) and apply it under Slackware.

The best OS for learning assembler is no OS at all. Interfacing with an OS can be complicated, and while learning, you want to simplify. Get any old x86 PC that can boot DOS from a floppy. Write OS agnostic code that fiddles bits on peripheral chips, does some interrupt servicing, etc all in real mode. Learn how to access the screen, keyboard, and storage devices. Once you've got the hang of it, start writing some protected mode stuff.
There are small trainer boards available that may have other CPUs, and which are intended for your objective. You should be able to find one on e-bay for very little money. You will also want some online or printed instruction set reference material, as well as datasheets for the hardware you're accessing.
--- rod.

I agree. It depends on which type of systems you are interesting in developing for... furthermore, you can actually get ASM emulators for different systems, which give you a graphical interface of the system's components.

The best OS for learning assembler is no OS at all. Interfacing with an OS can be complicated, and while learning, you want to simplify. Get any old x86 PC that can boot DOS from a floppy. Write OS agnostic code that fiddles bits on peripheral chips, does some interrupt servicing, etc all in real mode. Learn how to access the screen, keyboard, and storage devices. Once you've got the hang of it, start writing some protected mode stuff.
There are small trainer boards available that may have other CPUs, and which are intended for your objective. You should be able to find one on e-bay for very little money. You will also want some online or printed instruction set reference material, as well as datasheets for the hardware you're accessing.
--- rod.

A good starting point would be to learn the basic 8086 assembly language. Once you have that basic mastered, it is a simple matter to extend your knowledge to x86 and x86_64 systems.

NASM is a good assembler (comes with Slackware) and easy to use. If you install DOSBox on your system then NASM will directly generate *.COM files (< 64K) which spares you all the hassles of segmentation.

Well, x86 segment registers are a source of genuine disgust. So I'd suggest some other architecture.

And I agree with that; at least that they disgust a lot of people. Start with a more modest instruction set, and the accordant assembler.
'Learning assembler' is really two or three different things. It is learning how the CPU executes code at a very low level, and how the hardware actually works. It is learning a language within a language. When one learns the assembler language for a CPU, the instruction set is very specific to that CPU, yet the concept of assembler language programming is a transferable skill. Since any hardware capable of supporting an OS is probably best programmed using high level languages these days, it follows that the reason to use assembler programming is because the hardware resources are constrained, and so learning assembler is also about dealing with low-level components at the register level and understanding some hardware concepts such as machine cycles, buses, hardware logic and even standard hardware design idiom.
Understanding how a CPU works at the assembler level can be extremely revealing for understanding some high level language constructs, especially C. I was fortunate to have learned assembler long before I saw my first C compiler. If everyone had the same progression, I'm convinced we would have a lot of much better C programmers.

And... Since any hardware capable of supporting an OS is probably best programmed using high level languages these days ...

Well, I do not quite agree with that. For example, for an interrupt service routine one needs to save registers on stack (if we are talking about a stack machine), and then to restore the registers at the routine exit. High level languages do not have CPU register notion ("C" "register" keyword doesn't count - it's something different).

The amount of code which needs to be written in assembly is really tiny compared to the whole kernel, but still the code is necessary.

The best way to learn asm is writing functions (not whole programs) that use C calling conventions and are called from some high level language that can call C (most can) and that you are comfortable programming in. For me that is C++, but I have also coded asm functions to be called from Java via C interface and from actual C.

Quote:

Originally Posted by theNbomr

The best OS for learning assembler is no OS at all.

I totally disagree.

Quote:

Interfacing with an OS can be complicated,

Not so complicated on Linux. But I still don't recommend writing asm code that interfaces with the OS.

Quote:

while learning, you want to simplify.

That is the reason behind my suggestion and the reason I disagree with your suggestions.

The way to learn the required essentials of asm with a minimum of distractions from obscure side issues, is to write asm functions to be called via C calling standard.

Quote:

Write OS agnostic code that fiddles bits on peripheral chips, does some interrupt servicing, etc all in real mode.

That involves learning very little about asm, while learning an enormous amount of obsolete obscure details about IBM PC real mode hardware.

Quote:

Originally Posted by psionl0

A good starting point would be to learn the basic 8086 assembly language. Once you have that basic mastered, it is a simple matter to extend your knowledge to x86 and x86_64 systems.

I totally disagree.

16-bit x86 is a lame, idiosyncratic and obsolete asm. Learning it is a waste of time. You can start with x86_64.

Quote:

NASM is a good assembler

GNU as is a better assembler. It is a lot easier on Linux to just start with gnu assembler syntax and stick with it. Even if you want to mix Windows and Linux work, using cygwin gnu assembler under Windows might be better than using NASM.

Quote:

Originally Posted by Holering

What's a good operating system to use for learning assembly and familiarizing myself with it?

That really doesn't matter much. I prefer Linux to Windows for that, but not by much.

Using a debugger is a valuable tool in learning asm. Stepping through asm code generated by a compiler is part of a good approach to learning asm. Visual Studio is better at stepping through asm code than GDB, especially stepping through the asm code of something compiled with optimization turned on, which is better for learning. But a decent GUI front end for GDB is OK for that same purpose, and lots of other factors that affect learning asm are better on Linux.

If you already chose Linux over Windows, there is almost no reason any specific distribution of Linux might be better or worse for learning asm.

I think those are a terrible way to start learning asm. They probably also a terrible way to use asm, even once you know a decent amount of asm. But that is a more complicated question.

Almost regardless of why you want to learn asm, I think the best starting point is what I already suggested: First learn to write x86-64 functions to be called by the C calling convention.

Almost any other entry point to asm involves a massive amount of obscure detail specific to that entry point, that initially swamps out the core asm aspects of what you are learning.

In learning C callable asm functions, you have a small area of "side" learning: You need to learn which registers are used in which ways by the calling standard. If you start with only passing integers and pointers to/from functions (not passing or returning structures or floating point by value), the whole topic of the calling convention reduces to two simple lists of registers. Maybe you want to learn how to pass/return non integers by value later, but actually you will usually want to pass/return non integers by pointer anyway.

The path after or instead of of the first step I proposed depends on where you are going with asm:
A) Learning asm to get better at coding and debugging in other languages: I think for most software engineers, that is the best reason to learn asm. For that, learning C callable function asm code is all you ever need.
B) Learning asm to write code that will run faster than compiled code: C callable asm is still the only kind you need. You won't want to write whole programs in asm, just a few critical functions. Of course you'll need to learn a LOT about instruction timing and cache issues.
C) Learning asm to be able to write an OS: There are many specialized aspects of asm that are used only in coding an OS and even in an OS are used very little. Those are a giant new topic to learn, and that topic is best learned after learning the basics of asm in an easier place (C callable functions).
D) Programming super low cost micros: For example, I used to reprogram several models of infrared remote controls in two different asm architectures to do things different and more convenient than those remote controls were designed to do by their manufacturer. For that purpose, forget about learning any x86 first. Super low cost micro processors today are too different from any x86 architecture. Select a specific low cost micro and get an emulator for it.

The best way to learn asm is writing functions (not whole programs) that use C calling conventions and are called from some high level language that can call C (most can) and that you are comfortable programming in. For me that is C++, but I have also coded asm functions to be called from Java via C interface and from actual C.

I totally disagree.

...

You may disagree as long as you want, but HW proper has no OS. If you want to design a CPU-based device, the CPU first of all must get out of reset. I.e. to start fetching and executing instructions. So the very first instructions to be executed by CPU are in assembly. This is because there is "nothing" yet, for example, CPU registers have random values in them. The only defined register is PC (Program Counter), i.e. the register holding address of the next command to be fetched. And HW reset sets that register, disables interrupts, etc.

In my life I first had to design such CPU based HW, and later I became a VLSI designer. And for CPU simulation we needed routines in assembly. By the way, simulation speed was about 1 CPU clock per wallclock second.