How to Write First Program in Assembly Language

Creating your first assembly program is an exciting step in understanding the fundamentals of assembly language programming. Here's a step-by-step guide to writing a simple assembly program that prints "Hello, world!" to the console:

A simple assembly program typically consists of the following steps:

  1. Data Segment: This section defines the data variables used in the program.
  2. Code Segment: This section contains the instructions that the processor executes.
  3. Main Procedure: This is the starting point of the program.

Setting Up the Development Environment

  1. Choose a text editor: A simple text editor like Notepad++ or Sublime Text is sufficient for writing assembly code.
  2. Assembler and a linker: You'll need an assembler and a linker. For x86 assembly, you might use NASM (Netwide Assembler) as the assembler and LD (GNU Linker) for linking.
Example for NASM:
; Hello World program in NASM for x86 section .data hello db 'Hello, World!', 0 section .text global _start _start: ; write the string to stdout mov eax, 4 mov ebx, 1 mov ecx, hello mov edx, 13 int 0x80 ; exit the program mov eax, 1 xor ebx, ebx int 0x80

In this example, we define a data section with a string, and a text section where we define the entry point _start and use system calls to write to the console and exit.

Line by line explanation:
; Hello World program in NASM for x86 section .data hello db 'Hello, World!', 0
  1. section .data: This declares the start of the data section, where you define variables and constants. Here, hello is declared as a null-terminated string with the value 'Hello, World!'.
section .text global _start
  1. section .text: This declares the start of the code section, where you write the main logic of your program.
  2. global _start: This declares the entry point of the program as _start. The underscore before _start is a convention to denote a global label.
_start: ; write the string to stdout mov eax, 4 ; System call number for sys_write mov ebx, 1 ; File descriptor for stdout mov ecx, hello ; Pointer to the string to be printed mov edx, 13 ; Length of the string int 0x80 ; Interrupt to invoke the kernel and perform the system call
  1. _start:: This is the entry point label. The program execution begins here.
  2. mov eax, 4: Moves the value 4 into the eax register, which is the system call number for sys_write (write to file).
  3. mov ebx, 1: Moves the value 1 into the ebx register, which is the file descriptor for standard output (stdout).
  4. mov ecx, hello: Moves the address of the hello string into the ecx register.
  5. mov edx, 13: Moves the value 13 into the edx register, indicating the length of the string.
  6. int 0x80: Triggers a software interrupt (syscall) with the value 0x80, invoking the kernel to perform the system call. In this case, it will write the string to stdout.
; exit the program mov eax, 1 ; System call number for sys_exit xor ebx, ebx ; Exit code 0 int 0x80 ; Interrupt to invoke the kernel and perform the system call
  1. mov eax, 1: Moves the value 1 into the eax register, which is the system call number for sys_exit (exit the program).
  2. xor ebx, ebx: Exclusive OR operation with ebx and itself, effectively setting ebx to 0, which is the exit code.
  3. int 0x80: Triggers a software interrupt (syscall) with the value 0x80, invoking the kernel to perform the system call. In this case, it will exit the program with the specified exit code.

Save the Assembly Code

Copy the assembly code into a file. Let's call it hello.asm.

Assemble the Code with NASM

Open a terminal and navigate to the directory containing your hello.asm file. Use NASM to assemble the code:

nasm -f elf hello.asm

This command tells NASM to assemble the code for the ELF (Executable and Linkable Format) format, which is commonly used on Unix-like systems.

Link the Object File with LD

After assembling, you'll have an object file (hello.o). Now, use the linker (LD) to create an executable:

ld -m elf_i386 -s -o hello hello.o
  1. -m elf_i386: Specifies the target architecture (32-bit x86).
  2. -s: Removes unnecessary information to create a smaller executable.
  3. -o hello: Specifies the output file name (hello in this case).

Run the Executable

Now that you have an executable named hello, run it:

./hello

This should output "Hello, World!" to the console.

Note: If you encounter permission issues, you might need to make the file executable:
chmod +x hello

Now you've successfully assembled, linked, and run the assembly program on a Unix-like system. Keep in mind that the process might vary slightly depending on your specific development environment and operating system.

This program essentially prints "Hello, World!" to the console and then exits with a status code of 0. The system calls (sys_write and sys_exit) are performed through software interrupts using the int 0x80 instruction.

Conclusion

Writing your first assembly program is a valuable learning experience that introduces you to the fundamentals of low-level programming. By understanding the instructions and how they interact with the hardware, you gain a deeper appreciation of how computers execute programs.