Assembly Language - Basic Syntax

This chapter introduces the basic structure, syntax rules, and writing conventions of NASM assembly programs, helping you understand the skeleton of assembly code.


Basic structure of an assembly program

A complete NASM assembly program usually consists of the following parts:

Example

; File path: structure.asm
; Example of basic NASM program structure

section .data                       ; Data section: stores initialized data
    ; Define variables and constants here
    msg db 'Hello, EXAMPLE!', 0xA
    len equ $ - msg

section .bss                        ; BSS section: stores uninitialized data
    ; Reserve memory space here
    buffer resb 64                  ; Reserve a 64-byte buffer

section .text                       ; Code section: stores executable instructions
    global _start

_start:
    ; Write program logic here
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, len
    int 0x80

    mov eax, 1
    mov ebx, 0
    int 0x80
SectionPurposeCharacteristics
.dataStores initialized global variables and constantsSize and content determined at compile time, stored in the executable file
.bssStores uninitialized global variablesSpace is allocated only at runtime, does not occupy executable file size
.textStores executable machine instructionsRead-only, contains all the program's logic code

At least.textsections are required to form a valid assembly program. If there is no data, can omit the.dataand.bsssection.


Assembly statement format

The general format of each assembly statement is:

[标签:]   指令助记符   [操作数1 [, 操作数2 [, 操作数3]]]   [; 注释]

Explanation of each part:

PartRequired?Description
LabelOptionalA symbolic name representing a memory address, ending with a colon
Instruction mnemonicRequiredSuch as mov, add, sub, etc., tells the CPU what to do
OperandOptional (some instructions have no operand)The data object operated on by the instruction, can be a register, memory address, or immediate value
CommentOptionalStarts with a semicolon and continues to the end of the line

Example

; Examples of various statement formats

; Instruction only, no operand
ret                     ; Return from subroutine

; Instruction + single operand
push eax                ; Push the value of eax onto the stack
inc ecx                 ; Add 1 to ecx

; Instruction + two operands (most common)
mov eax, 42             ; Copy 42 into the eax register
add ebx, ecx            ; ebx = ebx + ecx

; With a label
loop_start:             ; Label: marks the start of the loop
    dec ecx             ; Subtract 1 from ecx
    jnz loop_start      ; If ecx is not 0, jump back to loop_start

Comment conventions

NASM usessemicolon (;)to denote comments; content from the semicolon to the end of the line is ignored by the assembler.

Example

; Full-line comment: explains the purpose of the following code block
; Calculate the sum of two numbers and output the result

mov eax, 10             ; Inline comment: put 10 into eax
add eax, 20             ; Inline comment: add 20 to eax, now eax = 30

Comments are extremely important in assembly code. Without comments, even the author may not understand the assembly code after a few weeks. Develop the habit of writing a comment for every instruction.


Identifier naming rules

Identifiers (labels, variable names, constant names, etc.) must follow the following rules:

RuleDescription
Composition charactersLetters, digits, underscore _, dot ., question mark ?, @, $, #, etc.
Starting characterMust begin with a letter, underscore, dot, or question mark; cannot begin with a digit.
Case sensitivityCase-sensitive by default (can be modified via compilation options)
Reserved wordsCannot have the same name as instruction mnemonics, register names, or NASM keywords.

Example

; Legal identifiers
my_variable:            ; Starts with a letter + underscore
.loop_start:            ; Starts with a dot (local label)
?error_handler:         ; Starts with a question mark
counter2:               ; Letter + digit

; Illegal identifiers (for reference only, do not use)
; 1st_value: ; Error: cannot start with a digit
; mov: ; Error: mov is a reserved word
; my-variable: ; Error: hyphen is not a legal character

Pseudo-instructions (Directives)

DirectivesAre commands to the assembler, not instructions to the CPU; they control the assembly process and define data structures.

DirectivesPurposeExample
dbDefine byte (1 byte)byte_val db 0x55
dwDefine word (2 bytes)word_val dw 0x1234
ddDefine double word (4 bytes)dword_val dd 0x12345678
equDefine constantMAX_SIZE equ 256
resbReserve byte spacebuffer resb 128
reswReserve word spacewbuf resw 64
resdReserve double word spacedbuf resd 32
%defineMacro-defined constant%define COUNT 10

Case conventions

NASM, by default, for labels and identifiersis case-sensitive.:

Example

; Example of case sensitivity

section .data
    msg db 'EXAMPLE', 0       ; Define variable msg

section .text
    global _start

_start:
    mov eax, MSG             ; Error: MSG and msg are different (unless case-insensitive mode is enabled)
    mov eax, msg             ; Correct: msg exactly matches the definition

    MOV EAX, 42              ; Syntactically correct: instruction mnemonics are case-insensitive
    mov eax, 42              ; Recommended style: use lowercase for better readability

Instruction mnemonics and register names are case-insensitive (MOV、Mov、movsame effect), but the recommended style is uniformly lowercase.


Numeric representation

NASM supports numeric representation in multiple bases:

Example

; Representation of different bases in NASM

mov eax, 42             ; Decimal: write the number directly
mov eax, 0x2A           ; Hexadecimal: 0x prefix (recommended style)
mov eax, 2Ah            ; Hexadecimal: h suffix
mov eax, 0o52           ; Octal: 0o prefix
mov eax, 52o            ; Octal: o suffix
mov eax, 101010b        ; Binary: b suffix
mov eax, 0b101010       ; Binary: 0b prefix

Recommended:0xuse prefix for hexadecimal (e.g.,0x2A), so it is less likely to be confused with labels.


A complete syntax example

The following program comprehensively uses the above syntax elements to calculate the sum of 1 to 10 and output it:

Example

; File path: sum.asm
; Calculate 1+2+...+10 and output the resulting character

section .data
    result db 0                 ; Store the calculation result (1 byte)
    newline db 0xA              ; Newline character

section .text
    global _start

_start:
    ; Initialize registers and variables
    mov ecx, 10                 ; Loop counter: count down from 10
    mov eax, 0                  ; eax stores the accumulated sum, initially 0

sum_loop:                       ; Loop start label
    add eax, ecx                ; eax = eax + ecx
    dec ecx                     ; ecx decremented by 1
    jnz sum_loop                ; If ecx != 0, continue the loop

    ; At this point eax = 55 (10+9+...+1)
    add eax, '0'                ; Convert number to ASCII character ('0'=48, 55+48=103='g', incorrect)
                                ; Actual demonstration requires more complex conversion, see later chapters

    ; Here only output result (simplified demonstration)
    mov [result], al            ; Store the accumulated result into result

    ; Exit program
    mov eax, 1
    mov ebx, 0
    int 0x80

Note: In the above example, adding '0' directly is only correct when the number is in the range 0-9. Converting numbers with two or more digits will be explained in detail in later chapters.

Other extensions