NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: Gunner on August 04, 2012, 10:45:19 PM
-
Been looking over the NASM docs, and searching the net and the answer eludes me. I am beginning the process of porting one of my MASM windows app over to Linux making it a terminal app in the process for the time being.
Don't want to write a command line parser ATM, so I came across getopt (http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html) and it does what I want. Except I want to expand it by using getopt_long. Problem is, this function uses a structure that I have no idea how to use.
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
The C code would initialize it like this:
static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{0, 0, 0, 0 }
In MASM, without using a structure I could do this in the data section:
long_options dd offset szAdd, 1, 0, 0, offset szAppend, 0, 0, 0, offset szCreate, 1, 0, offset szC, 0, 0, 0, 0
How do I use this structure?
-
Let me answer my own question:
long_options dd szAdd, 1, 0, 0, szAppend, 0, 0, 0, szCreate, 1, 0, 0, 0, 0, 0, 0
Works just fine. But I still would like to know how to use that structure.
-
I'm sure Frank or Keith will provide a better answer about structures than I, but what I would like to suggest is parsing command line options and subsequent environment variables without getopt.
I've written a command line parser in MASM for M$ and functionally it did nothing more that what linux is already doing. If you emit strings in GDB using x/80s 0x7fffffffe50d, you'll not only find all the arguments passed to your application, but a whole host of other information about your system and application. Keep in mind, the address depicted in example is always different, but always the contents of stack + 4.
To use getop IMHO has merit when using "C", but we are afforded a lot simpler way of doing things in NASM or more specifically assembly because we are not confined with the idiosyncrasies of higher level languages.
-
Let me answer my own question:
long_options dd szAdd, 1, 0, 0, szAppend, 0, 0, 0, szCreate, 1, 0, 0, 0, 0, 0, 0
Works just fine. But I still would like to know how to use that structure.
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
struc option
.name: resd 1
.has_arg: resd 1
.flag: resd 1
.val: resd 1
endstruc
static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{0, 0, 0, 0 };
%define required_argument 1
%define no_argument 0
long_options:
long_options_0:
istruc option
at option.name, dd szAdd
at option.has_name, dd required_argument
at option.flag, dd 0
at option.val, dd 0
iend
long_options_1:
istruc option
at option.name, dd szAppend
at option.has_name, dd no_argument
at option.flag, dd 0
at option.val, dd 0
iend
long_options_2:
istruc option
at option.name, dd szCreate
at option.has_name, dd required_argument
at option.flag, dd 0
at option.val, dd 0x00000063
iend
long_options_3:
istruc option
at option.name, dd 0
at option.has_name, dd 0
at option.flag, dd 0
at option.val, dd 0
iend
In the assembly initialization you'll notice I added extra labels with a numeric index suffix to make accessing the structures easier later on. This isn't specifically required. STRUC and ISTRUC can seem "wordy" but (IMO) it adds a bit of readability.
-
Outstanding, thank you!