How to use scanf in NASM?
Thanks Preet. I made a simple example based on your code to illustrate the use of scanf.
Program that requests an integer and prints it out to the screen:
section .text
global main
extern printf
extern scanf
section .data
message: db "The result is = %d", 10, 0
request: db "Enter the number: ", 0
integer1: times 4 db 0 ; 32-bits integer = 4 bytes
formatin: db "%d", 0
main:
; Ask for an integer
push request
call printf
add esp, 4 ; remove the parameter
push integer1 ; address of integer1, where the input is going to be stored (second parameter)
push formatin ; arguments are right to left (first parameter)
call scanf
add esp, 8 ; remove the parameters
; Move the value under the address integer1 to EAX
mov eax, [integer1]
; Print out the content of eax register
push eax
push message
call printf
add esp, 8
; Linux terminate the app
MOV AL, 1
MOV EBX, 0
INT 80h
This is the first post that shows up when you search for scanf
in assembly, so, even if its a 4 years old post, I think it should be correct.
Oukei, so, to call scanf
in NASM assembly you need to:
- Extern scanf
- Prepare a formatation for you scanf
- Prepare the variables or single variable to store the values expected
- Push the parameters in backward order
- Call scanf
- Restore stack
So, lets say you're traying to
scanf ("%d %d", &val1, &val2);
and following the list:
... 1.
section .text
extern scanf
...
2. This is the first parameter you pass to your C scanf
, it says what will you get. One integer, two, a float, string, char... In this case, two integers separated by a space (also works with Enter)
section .data
fmt: db "%d %d",0
... 3.
section .bss
val1: resd 1
val2: resd 1
... 4 5 6. Note that you push the address of the variables, not its content (i.e. [var])
push val2
push val1
push fmt
call scanf
add esp, 12
Also note that you have to add 12 to the stack pointer because you pushed 3 double word parameters. So you add 12 bytes (3*4 bytes) to the stack to "jump" the parameters.
*I declared dword for the variables because %d
uses dword, just as printf
.
**The ,0
in the end of the formatation string is a sentinel character.
I found this 'Programming in NASM.PDF'
; add1.asm
SECTION .data
message1: db "Enter the first number: ", 0
message2: db "Enter the second number: ", 0
formatin: db "%d", 0
formatout: db "%d", 10, 0 ; newline, nul terminator
integer1: times 4 db 0 ; 32-bits integer = 4 bytes
integer2: times 4 db 0 ;
SECTION .text
global _main
extern _scanf
extern _printf
_main:
push ebx ; save registers
push ecx
push message1
call printf
add esp, 4 ; remove parameters
push integer1 ; address of integer1 (second parameter)
push formatin ; arguments are right to left (first parameter)
call scanf
add esp, 8 ; remove parameters
push message2
call printf
add esp, 4 ; remove parameters
push integer2 ; address of integer2
push formatin ; arguments are right to left
call scanf
add esp, 8 ; remove parameters
mov ebx, dword [integer1]
mov ecx, dword [integer2]
add ebx, ecx ; add the values ; the addition
push ebx
push formatout
call printf ; call printf to display the sum
add esp, 8 ; remove parameters
pop ecx
pop ebx ; restore registers in reverse order
mov eax, 0 ; no error
ret
Which is the asm version of this C function:
#include <stdio.h>
int main(int argc, char *argv[])
{
int integer1, integer2;
printf("Enter the first number: ");
scanf("%d", &integer1);
printf("Enter the second number: ");
scanf("%d", &integer2);
printf("%d\n", integer1+integer2);
return 0;
}