Assembly is the lowest level you can go besides writing machine code directly. There are multiple assembly variants, like x86, RISC-V, 6502 and such.
This will focus on the x86 variant.
Registers are like variables, but very fast and only a few.
Fun fact: a CPU’s bitness (16-bit, 32-bit, 64-bit, …) refer to the size of the registers (e.g a 32-bit CPU can hold a number up to 4.294.967.295)
Some special registers – by convention, not rule. These can be used as general purpose registers but some instructions may read/write to them automatically.
| Register | Specialty |
|---|---|
| rax | accumulator |
| rbx | base |
| rcx | counter |
| rdx | data |
| rdi | destination |
| rsi | source |
There are also ‘reserved’, auto-set registers that shouldn’t be accessed directly by the program:
| Register | Function |
|---|---|
| rsp | stack pointer |
| rip | instruction pointer |
| rbp | stack base pointer |
| eflags | status/condition |
Write values to registers.
To assign a value to a register, you can write mov rax, 5 to move 5 to the rax register. You can also move between registers with mov rax, rbx (copy contents of rbx to rax)
Add values to registers.
You can do add rax, 2 to add 2 to the rax register.
Subtract values from registers.
To subtract 3 from the rbx register, do sub rbx, 3.
Multiply a register with a value.
To multiply rax with 8, do mul rax, 8 (e.g if rax is 2 then it will be 16 after mul)
Most of this is taken from https://github.com/hackclub/some-assembly-required a really great introduction to assembly.
NASM Assembly Language Tutorials - asmtutor.com → this seems like a good place to jump to after some-assembly-required.
https://defuse.ca/online-x86-assembler.htm#disassembly → this could be useful to practice writing x86/64 assembly and see its machine code representation (how it’s actually interpreted by the computer, as bytes)
As sidenote knowledge (debugging) go through Assembly - Nightmare to prep assembly knowledge.