Skip to content

Latest commit

 

History

History
164 lines (112 loc) · 6.69 KB

learning-notes.md

File metadata and controls

164 lines (112 loc) · 6.69 KB

About

I'm learning NASM primarily on Linux but chosen partly because of support for both Linux and Windows. Actually using YASM assembler.

NASM uses Intel-style syntax, as opposed to AT&T/Gas-style (dst src rather than src dst, no %-prefix for registers). It's not the 'default' for Linux but seems to make the most sense for me as I want to develop for both Linux and Windows, and the syntax feels more comfortable and readable.

I've been looking at 32-bit so far as there seems to be no advantage to looking at 64-bit, and I have a passing familarity with the registers so hoping it becomes natural more quickly.

I'm writing this as I learn, as a quick-reference page for myself. That means not everything will be correct; please feel free to reach out if I misunderstood something.

References

a.k.a "things that I need to look up frequently..."

Registers

(Ref: 1, 2)

32 bits :  EAX     EBX     ECX     EDX
16 bits :   AX      BX      CX      DX
 8 bits :   AH  AL  BH  BL  CH  CL  DH DL

Think E = Extended and X = Register, then A, B, C and D.

A Accumulator register: It is used for I/O port access, arithmetic, interrupt calls, etc...

  • EAX generally contains the return of a function. If you see the EAX register just after a function call, chances are that EAX contains the return value of the function.
  • EAX and EDX are always implied in multiplication and division instructions
  • EAX can also be used as a temporary CPU memory for additions

B Base register: It is used as a base pointer for memory access; gets some interrupt return values.

C Counter register: It is used as a loop counter and for shifts; gets some interrupt values.

D Data register: It is used for I/O port access, arithmetic, some interrupt calls.

Honorary mention for [E]SP - [Extended] Stack Pointer; points to last item in the stack.

Status / FLAGS Register

(Ref: 1, 2)

Commonly Used:

PF (Parity Flag)

The parity flag (PF) indicates if the number of set bits is even or odd in the binary representation of the low 8 bits of the result of the last operation.

ZF (Zero Flag)

The Zero Flag (ZF) is set (1) when the result of an operation is zero. Otherwise, it is cleared (0).

SF (Sign Flag)

The Sign Flag (SF) is set (1) when the result of an operation is negative. Otherwise (positive result), it is cleared (0).

Is it very important to remember that many instructions change the bits of the FLAGS register, so you should act on flag values immediately (or save them for later use).

Syscalls

(Ref: 1, 2 (x64 only))

eax Name Source ebx ecx edx
1 sys_exit kernel/exit.c int - -
3 sys_read fs/read_write.c unsigned int char* size_t
4 sys_write fs/read_write.c unsigned int const char * size_t
5 sys_open fs/open.c const char * int int
6 sys_close fs/open.c unsigned int - -
13 sys_time kernel/time.c int * - -
                           ; example of using sys_write to write to stdout
    mov eax,4              ; Put the system call number in the EAX register.
    mov ebx,1              ; Store the arguments to the system call in the registers EBX, ECX, etc.
    mov ecx,the_string
    mov edx,the_string_len
    int 0x80               ; Call the relevant interrupt (80h).
                           ; The result is usually returned in the EAX register.

File Descriptors

(Ref: 1

A file descriptor is a 16-bit integer assigned to a file as a file id. When a new file is created or an existing file is opened, the file descriptor is used for accessing the file.

Standard Streams

fd stream
0 stdin
1 stdout
2 stderr

Jumps

(Ref: 1 (no HTTPS) / 1 (HTTPS Version), 2)

Unconditional

    jmp label    ; transfer flow, does not ret (call does)

Conditional

Jump to an address in the code segment (i.e., a label) based on the content of the FLAGS register.

The FLAGS register is updated by:

  • All instructions that perform arithmetic operations
  • The cmp instruction, which subtracts one operand from another but doesn't store the result anywhere

Use in conjunction with cmp. See 'status registers / flags' above.

Instruction Description Flags tested
JE / JZ Jump Equal or Jump Zero ZF
JNE / JNZ Jump not Equal / Jump Not Zero ZF
JG / JNLE Jump Greater / Jump Not Less or Equal OF, SF, ZF
JGE / JNL Jump Greater or Equal / Jump Not Less OF, SF
JL / JNGE Jump Less / Jump Not Greater or Equal OF, SF
JLE / JNG Jump Less or Equal / Jump Not Greater OF, SF, ZF

Examples:

JE / JZ - jump if ZF = 1

JNE / JNZ - jump if ZF = 0

Checks the state of one or more of the status flags in the FLAGS register (CF, OF, PF, SF, and ZF) and, if the flags are in the specified state (condition), performs a jump to the target instruction specified by the destination operand. A condition code (cc) is associated with each instruction to indicate the condition being tested for. If the condition is not satisfied, the jump is not performed and execution continues with the instruction following the Jcc instruction.

    mov eax,1              ; eax = 1
    mov edx,1              ; edx = 1
    add edx,eax            ; edx = eax + edx
    cmp edx,2              ; if edx == 2
    je good_stuff          ; jump if ZF is set

Flow Control

call vs jmp

Use call to (allow flow to) return, jmp and other jumps do not.

    _some_func:            ; (2) function executes
        <code>
        ret                ; (3) `pop`s the return address off the stack and
                           ; continue execution at that address

    call _some_func        ; (1) transfer flow to _some_func, and push the address
                           ; of the next instruction (below) to the stack
    <code>                 ; (4) execution continues here

Loops

(Ref: 1)

    mov ecx, 5             ; ecx ≔ 5
head:
    ; the code here would be executed 5 times
    loop head