Tutorial 9 (Nov 21): External pointer arrays, command line arguments, atoi()
These two three topics are not required for A5a, but you need them for A5b. We will cover these in Monday/Tuesday tutorials.
[external.s][1440B]
[command.s][1140B]
[atoi.s][813B]
The first two examples are from Professor Manzara's slides, although I've added a few more comments.
External pointer arrays
I like to relate back to things you've already learned, especially because the topics in A5 are relatively simple if you understood A3 and A4. You've previously worked with arrays already, storing multiple integers. Each integer was 4 bytes long. Using a base address and an offset (calculated from the index), you were able to load and store to/from the array.
With an external pointer array, we store pointers rather than integers. Recall that a pointer is an object which "points to" another object. Essentially, a pointer contains an address. When we passed pointers into subroutines in A4, we stored addresses into x0-x7, with the registers x0-x7 becoming pointers. Now recall all the string literals we have used in every program so far, which follow this format:
stringName: .string "cpsc355"
stringName is a pointer to the address (or memory location) which contains the string "cpsc355". An external pointer array contains pointers. Since ARMv8 is a 64-bit architecture, addresses are 64-bits (or 8 bytes). For this reason, the contents of our array are dwords (8 bytes).
[external.s] External pointer arrays |
// Credits: Professor Leonard Manzara i_r .req w19 .text spr_m: .string "spring" // each string is pointed to by its label .data .text // Program code is read-only, goes in .text mov i_r, 0 top: adrp x0, fmt // First argument to printf (string format) mov w1, i_r // Index to loop through seasons array adrp base_r, season_m // get the base address of our pointer array // use loop index to calculate offset bl printf // print the season loaded in x2 add i_r, i_r, 1 ldp x29, x30, [sp], 16 |
![]() |
![]() |
Command line arguments
Programs that can only take one input with a single output are not very useful. To provide different parameters, a program can take command line arguments, similar to how functions/subroutines can accept parameters. When we execute a program, we can include arguments like this:
./a5b 9 11 1990
These arguments are then passed into the main() subroutine. However, w0 DOES NOT contain the first argument. Instead, w0 contains the NUMBER of arguments that were passed in. In this case, there are four arguments: "./a5b", "9", "11", and "1990". The pointers to each argument are stored as an external pointer array, with x1 as the base address. Using x1 as the base address, and an index to calculate the offset, we can access each argument.
[command.s] Command line arguments |
// Credits: Professor Leonard Manzara i_r .req w19 // index for our loop (integer) // To load the values of each argument, you first get the base address of argv. Then you fmt: .string "%s\n" .balign 4 mov argc_r, w0 // copy argc (number of pointers) mov i_r, 0 // i= 0 top: adrp x0, fmt ldr x1, [argv_r, i_r, SXTW 3] // set up 2nd arg bl printf // call printf add i_r, i_r, 1 // i++ ldp x29, x30, [sp], 16 |
atoi(): converting ASCII string to an integer
When the user enters a number as a command line argument, it is saved as a string. To convert this into a number, we can use the atoi() function from the C library.
- Load the ASCII string from the command line arguments.
- Pass the string to atoi() in x0, which returns an int in w0.
[atoi.s] Converting ASCII string to an integer |
// Converts a number from ASCII string to int .text .balign 4 mov w19, 1 // the 1st arg (index 0) is the program name ldr x0, [x1, w19, SXTW 3] // x1 is the base address to the external pointer mov w1, w0 // set up 2nd arg for printf mov w0, 0 |