section .text
    global _start       ;must be declared for using gcc
_start:                     ;tell linker entry point
    mov edx, len    ;message length
    mov ecx, msg    ;message to write
    mov ebx, 1      ;file descriptor (stdout)
    mov eax, 4      ;system call number (sys_write)
    int 0x80        ;call kernel
    mov eax, 1      ;system call number (sys_exit)
    int 0x80        ;call kernel
section .data
msg db  'Hello, world!',0xa ;our dear string
len equ $ - msg         ;length of our dear string
This is a basic 32-bit x86 Linux assembly code to print "Hello, World!" on the screen (standard output). Build + run it with
nasm -felf -g -Fdwarf hello.asm
gcc -g -m32 -nostdlib -static -o hello hello.o
./hello
(Editor's note: or gdb ./hello to debug / single-step it.  That's why we used nasm -g -Fdwarf and gcc -g.  Or use layout reg inside GDB for disassembly+register view that doesn't depend on debug symbols.  See the bottom of https://stackoverflow.com/tags/x86/info)
Now I want to ask about how is this code working behind the scenes. Like what is the need for all these instructions
_start:                     ;tell linker entry point
        mov edx, len    ;message length
        mov ecx, msg    ;message to write
        mov ebx, 1      ;file descriptor (stdout)
        mov eax, 4      ;system call number (sys_write)
        int 0x80        ;call kernel
        mov eax, 1      ;system call number (sys_exit)
        int 0x80        ;call kernel
just to print "Hello, World!" and the statement
_start:
above! Is it the main function?
and the statement
int 0x80
why is it used at all? Can you guys give me a deep explaination of the basic working of this program.
 
     
    