I want to learn assembly, but the kind of tutorials i com across seem to adhere to one of two sides: either [relatively] high level or everything built from scratch. Personally, i want to learn from the ground up how it works, but the tutorials i leafed through seem to go directly into a 64-bit version where you can just write anything. For example:
section .data
hello: db 'Hello world!',10 ; 'Hello world!' plus a linefeed character
helloLen: equ $-hello ; Length of the 'Hello world!' string
section .text
global _start
_start:
mov eax,4 ; The system call for write (sys_write)
mov ebx,1 ; File descriptor 1 - standard output
mov ecx,hello ; Put the offset of hello in ecx
mov edx,helloLen ; helloLen is a constant, so we don't need to say
int 0x80 ; Call the kernel
mov eax,1 ; The system call for exit (sys_exit)
mov ebx,0 ; Exit with return "code" of 0 (no error)
int 80h;
num_to_string:
push ebp
mov ebp, esp
mov esp, ebp
pop ebp
Here is a basic hello world program that appears if i go on an asm compiler. It's using the e_x
registers already, without anything to be written beforehand.
Meanwhile, in a (possibly pretty dated) tutorial of a beginner trying learn to write a bootloader and sharing it (youtube playlist), he had to go through going from 16bit mode to protected 32bit mode and then to long mode (64bit).
I know the syntax varies based on architecture, but between the "bare-metal" one and the "high level" one, there seem to be clear differences in not exactly syntax, but how you code.
There is no such thing as "low level assembly" and "high level assembly". It's always the same thing put in different contexts.
For instance, the code you wrote makes heavy use of the OS (in this case int 80h
is a call to the Linux kernel) and you don't do pretty much by yourself, because you just put a few strings in memory, call the OS and that's it, you have a hello world in a console.
In the case you mention of writting a bootloader, you're in a masively different environment. The computer has pretty much nothing in memory and you must work your way out of that into loading a fully working OS, by passing though mode changes and the like.
Both things differ only in the environment they exists in. When you run on top of an OS, you are just an application that calls the OS, while the OS talks to the hardware, manage memory, writes to disk, handles CPU resources and the like. When you write a bootloader (or worse, an operating system), you must do all that by yourself.