lesson05.ppt

advertisement
‘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!)
Download