<!--
  canonical-url: https://www.avonture.be/blog/docker-assembly
  published:     2023-11-30
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Play with Docker and Assembly programming language

> Learn how to combine modern Docker technology with the classic x86 Assembly programming language. This guide provides a step-by-step "Hello, World!" example for both MS-DOS and Linux environments.

---
![Play with Docker and Assembly programming language](/img/v2/experiments.webp)

**TL;DR**

This article revives 1990s x86 Assembly nostalgia by assembling and running a "Hello, World!" `.asm` file with zero local install, using the `esolang/x86asm-nasm` Docker image from both a DOS/PowerShell console (`%CD%`) and Linux (`${PWD}`).

When I was younger than today, during my studies, I was playing with the x86 Assembly language on my `386DX40` computer; this was in the years 1993-1995. The beginning of Windows 3.1 that I did not like. *If someone had asked me if graphical interfaces would be successful, I would have said no, of course not.*

I remember that I wrote a resident program (TSR which stands for **T**erminate and **S**tay **R**esident) which, once loaded into memory, monitored the keyboard and recorded the keys that had been pressed in a file on the hard disk. Yes, it was a password stealer. Just for fun and, above all, for the challenge of it.

And now, in 2023, I was wondering if it was still possible to run `.asm` files on my computer.  It was an excellent reason for this article.

*The same nostalgia trip, one language later: [Play with Docker and Pascal](/blog/docker-pascal), where I compile Turbo Pascal sources I published thirty years ago.*

By searching on [Docker Hub](https://hub.docker.com/), I have found this image: <https://hub.docker.com/r/esolang/x86asm-nasm>

## Let's play in MS-DOS

Let's test our Docker image in DOS this time. Please start a **DOS** console and run `mkdir C:\tmp\assembly && cd C:\tmp\assembly` to create a folder called `assembly` in your DOS environment and enter it.

Please create a new file called `Hello.asm` with this content:

**Hello.asm**

```asm
; Our data section (i.e. our variables)
SECTION .data
    ; Our null terminated string
    hello: db 'Hello, World! This message comes from Docker.', 0

; Our entry point
SECTION .text
    global _start

_start:
    mov edx, 45    ; 45 is the length of our "hello" message
    mov ecx, hello ; The name of our variable is "hello"
    mov ebx, 1     ; We'll write to stdout
    mov eax, 4     ; System call number (sys_write)
    int 0x80       ; Triggers software interrupt 80

    mov ebx, 0     ; Next three lines are equivalent to exit 0
    mov eax, 1
    int 0x80
```

To run the script, just call Docker, like this:

```bash
$ docker run --rm -v %CD%:/code -w /code esolang/x86asm-nasm x86asm-nasm hello.asm
Hello, World! This message comes from Docker.
```

> **Of course you can play under Linux:**
>
> Just replace `%CD%` by `${PWD}` and the instruction will be recognized by Linux: `docker run --rm -v ${PWD}:/code -w /code esolang/x86asm-nasm x86asm-nasm hello.asm`

Same idea, different language: I've also played with [Pascal](/blog/docker-pascal), [Python](/blog/docker-python), and [Java](/blog/docker-java) using this same "zero local install" Docker approach.
