We have seen how to read input from stdin. However, if we wanted to read a number, such as an integer, it would be nice to not have to convert it from text to an integer ourselves. We will use the "scanf" function from the C library to do this for us.
Scanf uses a format specifier, much like printf. We will keep this simple, and use "%d" as the specifier, meaning an integer value. The code below can be used as a starting point.
extern printf ; the C function, to be called
extern puts ; the C function, to be called
extern scanf ; the C function, to be called
section .data ; Data section, initialized variables
format_str: db "%d", 0 ; The scanf format, '0'
prompt: db "Enter an integer number: ", 0
num: dd 0
confirm_str: db "You entered %d as the number.", 10, 0
section .text ; Code section.
global main ; the standard gcc entry point
main: ; the program label for the entry point
; Print the prompt
mov rdi, prompt ; First argument for printf (address of msg)
xor rax, rax ; Clear rax because printf is a variadic function
call printf ; Use printf instead of puts: no newline
; Call scanf
mov rsi, num ; Address of num for scanf
mov rdi, format_str ; Format string for scanf
xor rax, rax ; Clear rax because scanf is a variadic function
call scanf
; Now that we have the number,
; print it back out to the user.
mov rdi, confirm_str ; Format string
mov esi, [num] ; Load the value num to print
mov rax, 0
call printf
ret
Call this "scanf_example.asm", assemble it, link it, and run it.
Test it out 3 times (with 3 different numbers)
to verify that it works as expected.
We will use this again below.
Copy the code from part 1 to "lab14_pt2.asm" and update the comments accordingly. Keep the part that prompts the user for a number and uses scanf to read it. Load the number into a register, and multiply it with itself, then store the result in memory. Create a new string to print "square of the number is " followed by a number (i.e. "%d"). Use this string to print the result you obtained.
Test it out 3 times (with 3 different numbers) to verify that it works as expected.
Copy the code from part 2 to "lab14_pt3.asm" and update the comments accordingly. Keep the part that prompts the user for a number and uses scanf to read it. Load the number into a register, and multiply it with itself. Next, multiply it by itself again, then store the result in memory. Create a new string to print "cube of the number is " followed by a number (i.e. "%d"). Use this string to print the result you obtained.
Test it out 3 times (with 3 different numbers) to verify that it works as expected.
Questions:
div_loop:
xor rdx, rdx ; Clear rdx each time before division
mov rbx, 10 ; Set divisor to 10
div rbx ; Divide rax by 10, quotient in rax, remainder in rdx
; Cube the remainder
mov rcx, rdx ; Move remainder to rcx for cubing
imul rcx, rcx ; Square rcx
imul rcx, rdx ; Cube rcx (remainder)
add rsi, rcx ; Add cube of remainder to rsi
; Check if there are more digits to process
test rax, rax ; Test quotient for zero
jnz div_loop ; If quotient not zero, loop
For the input number, print a message that it is a Narcissistic Number or not.