commandline arguments How can an assembly language program
‘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 <arg 1> <arg 2> … • 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 ‘rax 2 uint’ subroutine to convert the number of arguments into a string of decimal numerals for printing msg: buf: len: _start: . section. ascii. quad . data “OK, the number of command-line strings was “ “ n”. - msg . section mov call . text (%rsp), %rax $buf, %rdi rax 2 uint # 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!)
- Slides: 11