global _start section .data str: db '0123456789',0xA strSize: equ $ - str stdout: equ 1 section .text _start: ; Print the string mov rdx, strSize mov rsi, str mov rdi, stdout mov rax, 1 syscall ; mov byte [rsi], 3 == *rsi = 3 ; Move the value of 3 into the address contained in register RSI ; Note the type specifier ; byte, word, dword ; The official syntax is ;mov byte ptr [rsi], 3 ; But the ptr is implicitly meant with the []'s, so nasm allows ; us to leave it out mov byte [rsi], 'a' mov rax, 1 syscall mov word [rsi], 'bc' mov rax, 1 syscall mov dword [rsi], 'defg' mov rax, 1 syscall ; "In 64-bit mode, a memory operand can be referenced by ; a segment selector and an offset. [...] ; The offset part of a memory address in 64-bit mode can be ; specified directly as a static value or through an address ; computation made up of one or more of the following components: ; Displacement -- An 8-bit, 16-bit, or 32-bit value. ; Base -- The value in a 64-bit general-purpose register. ; Index -- The value in a 64-bit general-purpose register. ; Scale factor -- A value of 2, 4, or 8 that is multiplied ; by the index value." ; In intel syntax, this is written as: ; [base + scale * index + displacement] ; Example: ; [rax + 2 * rbx + 0xdeadbeef] ; (most of these are optional; see below). mov byte [rsi], 'h' ; base only mov rax, 1 syscall mov byte [str], 'i' ; displacement only mov byte [str+1], 'j' ; displacement only too (assembler evaluates it) mov rax, 1 syscall mov rbx, 3 mov byte [rsi+2], 'k' mov byte [rsi+rbx], 'l' mov byte [rsi+2*rbx], 'm' mov byte [rsi+2*rbx+2], 'n' mov rax, 1 syscall ; Load Effective Address ; Calculate the address of the expression, it does NOT load the value! mov rbx, 2 lea rsi, [str+2*rbx] ; = rsi = str + (2 * 2) ; Due to this powerful feature it is often used with invalid ; addresses: you can use it to do generic calculations! mov rbx, -2 lea rdx, [strSize+2*rbx] ; print (strSize - 4) characters mov rax, 1 syscall ; Exit mov rax, 60 xor rdi, rdi syscall