Getting user input from the console
Getting user input from the console is not that much more complicated than printing. The following examples show how to read variables of different types and echo them back in a string. The printing of the variables will follow the examples on the previous page.
Echo a string
// echo_string.s
.global main
.extern scanf
.extern printf
.data
prompt:
.asciz "Enter a string: "
fmt_in:
.asciz "%s"
fmt_out:
.asciz "You entered: %s.\n"
buffer:
.skip 10 // 10 bytes for the string
.text
main:
// Prolog
stp x29, x30, [sp, -16]!
mov x29, sp
// Main code
ldr x0, =prompt // Load the prompt to x0
bl printf // Print prompt
ldr x0, =fmt_in // Load the prompt to x0, note the %s placeholder
ldr x1, =buffer // Load the address of the buffer to x1
bl scanf // Read from the console and store at buffer address
ldr x0, =fmt_out // Load format to x0, note the %s placeholder
ldr x1, =buffer // Load buffer addr to x1
bl printf // Print
end:
// Cleanup
mov x0, #0
ldp x29, x30, [sp], 16
RET
The data section contain four declarations.
The prompt variable does not have a newline (\n) character at the end. The cursor should remain at the end of the prompt line while the user types their string.
The fmt_in variable specifies that the input is to be read as a string (%s).
The fmt_out variable does have a newline character at the end and a string variable for inclusion.
Finally, the buffer variable is declared with ten adjacent memory locations for a string of up to ten characters.
When run the output looks like this:
andrew@master:~/assm2 $ ./echo_string
Enter a string: hello
You entered: hello.
andrew@master:~/assm2 $
Note that the scanf function uses a whitespace as the terminating character so the function will only read up to the first whitespace. If two words, separated by a whitespace, are entered, only the first word is echoed.
andrew@master:~/assm2 $ ./echo_string
Enter a string: hello world
You entered: hello.
andrew@master:~/assm2 $
Echo an integer
Reading and echoing integers requires chosing 32 or 64 bit integers. To make life simple this demonstration will show 64 bit values since there is no penalty for doing so.
// echo_string.s
.global main
.extern scanf
.extern printf
.section .data
prompt:
.asciz "Enter an integer: "
fmt_in:
.asciz "%ld"
fmt_out:
.asciz "You entered: %ld.\n"
integer:
.quad 0 // Variable declared and set to zero
.section .text
main:
// Prolog
stp x29, x30, [sp, -16]!
mov x29, sp
// Main code
ldr x0, =prompt // Load the prompt to x0
bl printf // Print prompt
ldr x0, =fmt_in // Load the prompt to x0, note the %d placeholder
ldr x1, =integer // Load the address of integer to x1
bl scanf // Read from the console and store at integer address
ldr x0, =fmt_out // Load format to x0, note the %d placeholder
ldr x1, =integer // Load integer addr to x1
ldr x1, [x1] // Load value at integer addr to x1
bl printf // Print
end:
// Cleanup
mov x0, #0
ldp x29, x30, [sp], 16
RET
The 64 bit option are the %ld in the fmt_in and fmt_out variables and the .quad in the integer declaration.
Echo a float
This is identical to the echo_int application except that the placeholders are %lf (long float) and the variable is declared as .double.
// echo_float.s
.global main
.extern scanf
.extern printf
.section .data
prompt:
.asciz "Enter a floating point number: "
fmt_in:
.asciz "%lf" // This MUST be %lf
fmt_out:
.asciz "You entered: %lf.\n" // This can be %f or %lf
float:
.double 0 // Variable declared and set to zero
.section .text
main:
// Prolog
stp x29, x30, [sp, -16]!
mov x29, sp
// Main code
ldr x0, =prompt // Load the prompt to x0
bl printf // Print prompt
ldr x0, =fmt_in // Load the prompt to x0, note the %lf placeholder
ldr x1, =float // Load the address of float to x1
bl scanf // Read from the console and store at integer address
ldr x0, =fmt_out // Load format to x0, note the %lf placeholder
ldr x1, =float // Load float addr to x1
ldr d0, [x1] // Load value at float addr to d0
bl printf // Print
end:
// Cleanup
mov x0, #0
ldp x29, x30, [sp], 16
RET