For 64 bit nasm:
For using scanf with nasm, you need to first have the statement before the .text section.
extern scanf
Now you need to first setup your stack using
push rbp
This is important if you don't want a segmentation fault. The stack pointer rsp must be aligned to a 16-byte boundary before making a call. The process of making a call pushes the return address (8 bytes) on the stack, so when a function gets control, rsp is not aligned. You have to make that extra space yourself, by pushing something or subtracting 8 from rsp. You can read more about it here.
Now, that your stack is ready, you need to first move your input formatted string in rdi register, followed by the arguments in rsi, rdx, rcx, r8, r9 in strict order.
Let's take the example of mimicking the c statement
scanf("%d %d", &a, &b);
The equivalent nasm code would be:
section .data
Input_format db "%d %d", 0
section .bss
var1: resd 1 ;reserves one double(4 bytes) for int variable
var2: resd 1
extern scanf
global main
default rel ; use this by default for efficiency. This is even mandatory if you run your code on macOS.
section .text
main:
push rbp
lea rdi, [Input_format] ;loading format
lea rsi, [var1]
lea rdx, [var2]
call scanf
pop rbp ;restores stack
;simulates return 0
mov rax, 0
ret
Below is the code which is prettier version of the above code. It prompts user for input, and prints the inputted number.
section .data
int_inMsg: db "Enter an integer value" , 10, 0 ;10 for new line, 0 for null
real_inMsg: db "Enter a real value", 10, 0
bool_inMsg: db "Enter a boolean value", 10, 0
arr_inMsg: db "Enter %d elements for array range %d to %d", 10, 0
intFormat db "%d", 0
section .bss
var1: resd 1
global main
extern printf
extern scanf
extern puts
extern exit
default rel
section .text
main:
push rbp ;setup stack
;printf("Enter blah blah\n");
lea rdi, [int_inMsg] ;first argument
xor rax, rax
call printf
;take input from the user
;scanf("%d", &var1);
lea rdi, [intFormat]
lea rsi, [var1]
xor rax, rax
call scanf
lea rdi, [intFormat]
mov esi, [var1] ;notice the [] for sending value of var1 instead of pointer to var1
xor rax, rax
call printf
; return
pop rbp ;restore stack
mov rax, 0 ;normal exit
ret
Thanks to @peter for his helpful and insightful comments.