Sometimes called assembly or ASM, an assembly language is a low-level programming language.

Programs written in assembly languages are compiled by an assembler. Every assembler has its own assembly language, which is designed for one specific computer architecture.

Why is ASM useful?

Machine language is a series of numbers, which is not easy for humans to read. Using ASM, programmers can write human-readable programs that correspond almost exactly to machine language.

  • Why is ASM useful?
  • Why is ASM a “low-level” language?
  • How is ASM different from a “high-level” language?
  • What is a “mid-level” language?
  • Is ASM portable?
  • Example: Hello, World! in 32-bit assembly, for Windows
  • Example: Hello, World! in 64-bit assembly, for Linux
  • Related information

The disadvantage is that everything the computer does must be described explicitly, in precise detail. The advantage is that the programmer has maximum control over what the computer is doing.

Why is ASM a “low-level” language?

Assembly is called a low-level programming language because there’s (nearly) a one-to-one relationship between what it tells the computer to do, and what the computer does. In general, one line of an assembly program contains a maximum of one instruction for the computer.

How is ASM different from a “high-level” language?

High-level languages provide abstractions of low-level operations which allow the programmer to focus more on describing what they want to do, and less on how it should be done. Programming this way is more convenient and makes programs easier to read at the sacrifice of low-level control.

Programs written in high-level languages never match the raw speed and efficiency of programs written in assembly. Examples of high-level languages include Python, Java, JavaScript, Clojure, and Lisp.

What is a “mid-level” language?

Mid-level languages or lower-level languages provide some high-level abstractions to make the programmer’s life easier, while still providing access to low-level operations. They are often used to write operating systems, so they are sometimes called system programming languages.

Programs written in mid-level languages can perform as well, or nearly as well, as programs written in assembly language. Examples of mid-level programming languages include C, C++, Ada, Nim, and Rust.

Is ASM portable?

No. Because assembly languages are tied to one specific computer architecture, they are not portable. A program written in one assembly language would need to be completely rewritten for it to run on another type of machine.

Portability is one of the main advantages of higher-level languages. The C programming language is often called “portable assembly” because C compilers exist for nearly every modern system architecture. A program written in C may require some changes before it will compile on another computer, but the core language is portable.

Generally speaking, the higher-level a language is, the fewer changes need to be made for it to run on another architecture. The lowest-level languages — machine language and assembly language — are not portable.

Example: Hello, World! in 32-bit assembly, for Windows

Here is “Hello, World” written for a 32-bit Intel processor. It also runs on a 64-bit processor. We will compile and run it on Windows 10.

global  _main
extern  _printf
section .text

_main: push message call _printf add esp, 4 ret message: db ‘Hello, World!’, 10, 0

To begin, open Notepad. Copy and paste the code above into a new text file, and save the file as hello.asm.

To compile the assembly, we use NASM, the Netwide Assembler. It can be downloaded at the NASM site.

nasm -f win32 hello.asm

When you run this command, NASM creates an object file. An object file contains machine code, but is not quite an executable file. Our object file is called hello.obj.

To create the executable, we use the 32-bit version of MinGW (Minimal GNU for Windows) which provides the gcc compiler. It can be downloaded at MinGW site.

gcc -o hello.exe hello.obj

hello

Hello, World!

Example: Hello, World! in 64-bit assembly, for Linux

Here is “Hello, World” written for a 64-bit Intel processor. We will compile and run it on 64-bit Linux.

    extern printf           ; the C printf function, to be called
    section .data           ; Data section, initialized variables

msg: db “Hello, world!”, 0 ; C string terminates with 0 fmt: db “%s”, 10, 0 ; The printf format, “\n”,‘0’ section .text ; Begin code section global main ; the standard gcc entry point main: ; the program label for the entry point push rbp ; set up stack frame, must be aligned mov rdi,fmt mov rsi,msg mov rax,0 ; can also be: xor rax,rax call printf ; Call C printf function pop rbp ; restore stack mov rax,0 ; normal, no error, return value ret ; return

Copy and paste this program into a new file called hello.asm.

Then, compile the assembly with NASM, which you can install with your package manager. For instance, on Ubuntu or Debian, you can install NASM using apt:

sudo apt update && sudo apt install nasm

Run this command to create your object file:

nasm -f elf64 hello.asm

The object file is named hello.o.

Next, use gcc to link this object file to the necessary libraries on your computer, and compile it to an executable file called hello:

gcc hello.o -o hello

Lastly, run the executable file:

./hello

Hello, world!

For reference, this is the same program, written in C:

#include <stdio.h> int main() { char msg[] = “Hello world\n”; printf("%s\n",msg); return 0; }

2GL, Assembler, Low-level language, Machine language, Programming terms

  • How to create a computer program.
  • See debugging routines for other examples of low-level assembly code and additional information about what each routine does.
  • For additional examples of assembly language, see the Happy Codings website.