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_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 $
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.
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