‘command-line’ arguments How can an assembly language program find out what the user typed on the command-line? Supplying arguments • Whenever a user launches any application by typing its file’s pathname at a terminal, it is possible to supply additional inputs in the form of command-line arguments: $ ./appname <arg1> <arg2> … • But how does that program find out what was typed? The shell’s setup • The system’s command-line interpreter will ‘parse’ the command-line input-string, and will setup an array of pointers to the line’s substrings, and provide the count of their number • Upon entry, this information will be at the top of the application’s stack The stack upon entry command-line: $ ./myprogram abc ijk xyz application’s stack NULL argv[3] argv[2] argv[1] argv[0] SS:RSP 4 Indirect addressing • Your application can discover the number of strings that were typed by using indirect memory addressing via register RSP argc: _start: .section .data .quad 0 # space for argument count .section .text # copy the number of command-line arguments to ‘argc’ mov (%rsp), %rax # get the argument-count mov %rax, argc # and store it in a variable … Showing ‘argc’ • You can use our ‘rax2uint’ subroutine to convert the number of arguments into a string of decimal numerals for printing msg: buf: len: _start: .section .ascii .ascii .quad .data “OK, the number of command-line strings was “ “ \n” . - msg .section mov mov call .text (%rsp), %rax $buf, %rdi rax2uint # get the ‘argc’ value # point EDI to buffer # convert number to string # now use the ‘sys_write’ system-call to print the ‘msg’ Showing the args • You can easily design a program-loop that displays each of the command-line’s args 3 argv[0] argv[1] argv[2] NULL RSP • You have two choices for how you control your loop’s termination: – You can use the ‘count’ of the pointers – You can stop when the next pointer is NULL Array-addressing • You also have choices about how you will access elements in the array of pointers – You can use an array-pointer that advances – You can use an array-index that increments • In either case, you’ll need to know how to use indirect forms of memory-addressing displacement( base, index, scale ) The advancing pointer # select a register to be used as a pointer to the current array-element lea 8(%rsp), %rbx # point RBX to argv[0] nxarg: mov (%rbx), %rsi # get next array-element or %rsi, %rsi # is this pointer null? jz finis # yes, finished # else display string whose address is in RSI add jmp finis: $8, %rbx nxarg # advance array-pointer # and process its entry The incrementing index # select a register to be used as an index for the current array-element xor %rbx, %rbx # initialize array-index nxarg: mov 8(%rsp, %rbx, 8), %rsi # get next array-element or %rsi, %rsi # is the pointer null? jz finis # yes, finished # else display string whose address is in RSI inc jmp finis: %rbx nxarg # increment array-index # and process its entry Demo: ‘myargs.s’ • This program demonstrates one way that an assembly language application can do a display of its command-line arguments • It decrements the ‘argc’ counter at (%rsp) to determine when the loop will terminate • Why do you think the programmer did not use register RCX as the loop-counter for this application? (Try it!)