Want to master command line arguments in Yasm assembly? This video breaks down how to access and process args in x86-64 hybrid programs linked with GCC. From understanding argv and argc to looping through arguments, we cover it all with practical examples. Perfect for programmers diving into assembly or looking to level up their low-level coding skills. Check out my other videos for more on Yasm and pure assembly! Subscribe for more coding tutorials. #AssemblyProgramming #YasmAssembly #GCC #x86_64
Introduction 00:00:00
Command Line Arguments Overview 00:00:03
Yasm Assembly and GCC Linking 00:00:07
Hybrid Program Explanation 00:01:27
Makefile Overview 00:02:16
Assembly Program Structure 00:03:16
Main Entry Point and Registers 00:03:51
Accessing Command Line Arguments 00:04:26
Argument Count and Pointers 00:05:03
Loop Initialization for Arguments 00:08:57
Loop Logic and Dereferencing 00:10:52
Printing Arguments 00:13:02
Incrementing Pointers in Loop 00:14:08
Running the Program 00:15:35
Practical Application of Arguments 00:17:24
Conclusion and Next Steps 00:17:51
Call to Subscribe and Outro 00:18:22
Thanks for watching!
Find us on other social media here:
- https://www.NeuralLantern.com/social
Please help support us!
- Subscribing + Sharing on Social Media
- Leaving a comment or suggestion
- Subscribing to our Blog
- Watching the main “pinned” video of this channel for offers and extras
Hello there. In this video,
I’m going to talk to you about how to accept incoming command line arguments to
an x86-64 Yasm assembly program that is probably linking to
GCC and is thus probably a hybrid program under the hood.
If you don’t know how to program in Yasm assembly yet,
check out my other videos. If you don’t understand command line arguments yet,
yet check my other videos I’m going to assume a lot of knowledge here I’m
really just going to show you how to pull the arguments inside of assembly
using using the GCC setup that they’ve given you so just a quick just a very
quick recap this is not a command line arguments video if we have the program
echo and we give it like one argument of just the word hello then it’s it’s
going to receive one command line argument in addition to its program
echo as argument zero and hello as argument index one.
And it’s just going to be able to look at them and say,
oh, the user wants me to print this hello string.
So it just prints it.
And so that’s kind of how you can tell a program what to do,
either when you’re running them directly
or having one program automate another program.
Anyway, so in our Yasm assembly programs,
how do we actually get that out?
Well, for starters, we are dynamically linking.
Sorry, not dynamically linking.
We are linking a hybrid program.
So I just want to make sure that you understand this is the right video for you.
If you’re trying to do this in pure assembly, or if you need to know that for some reason,
then you’ll probably want to watch the next video that I publish.
But for now, this is a hybrid program.
Hybrid programs, for those of you who don’t know, it just means you have modules that
are written in different source code and they’re compiled differently, different source code
languages.
So you might have a source code file that’s written in C++ another one that’s written in C another one that’s written in assembly
And you compile them all down to their own object files and then you link them together into an executable
If GCC is part of the linking process
Then it’s going to end up giving you a main function as your entry point and it’s going to make things a little bit easier
Here’s my make file. I’m just going to skim through it real fast. This is not a make file video
So if you don’t understand it go look at my other videos
But basically I’m just going to assemble with Yasm and I’m going to use G++ as the linker
and I’m going to gobble up all of the object files. Here’s like a little menu.
I have a target for running and building only. And here’s the main thing that I’m doing. This
is not really a hybrid program. This is just kind of a pure assembly program that is linked with GCC,
but you can imagine you could add other source files in C and C++ and still totally get away
GCC. But anyway, I’m just compiling one source code of assembly and,
and compiling it down to an object file right here.
And then when it comes time to linking, uh, you can kind of tell here, uh,
especially if you’re familiar with make files that I’m just gobbling up all the
object files and linking them together into the executable.
So that’s as far as I’ll go there again,
I’ve got another video that totally explains a lot more in my assembly program.
video just for pure assembly so if you don’t understand assembly see my other videos but for
now we’re just going to say i’ve got a data section it’s got a couple of null terminated strings we’ve
got a hello message a begin message a goodbye message carriage return line feed string i’ve
got the system call codes for you know printing to standard output and to exit the program and then
i’ve got the standard output file handle and then my exit code zero for success again this is all
other videos. So because I’m linking with GCC, my text section here, the actual place where the
instructions are, not the data, is going to have a main entry point. So of course, if you had a
hybrid program, you could have main somewhere else in a different module and then just call on a
function that was inside of assembly. You could totally do that. But for now, I’m just going to
say this is the only source code file. So I mark main as global and I put main right here. And then
I preserve all of the Kali saved registers that I’m supposed to by pushing them at the beginning and popping them in reverse order at the end.
And then I return a return value.
Standard assembly stuff covered in other videos.
But here’s the key for getting command line arguments in assembly.
If you recall, the ABI specifies that in x86-64 programs, the first argument is always supposed to come into a function as RDI in the RDI register.
register or rather I should say the first integer argument I haven’t talked
about to float arguments in any of my videos yet in the future you should
probably search for other videos that that explain how to do float arguments
but for now all of the arguments I’m talking about in this video are just
integer arguments and pointer arguments which is kind of the same thing a
pointer is an integer it’s a 64-bit integer but we’ll just use it as a
using it as an integer so anyway first argument comes in on RDI second argument
comes in on RSI and you can imagine that basically this is the thing you’re
probably used to seeing in your C++ programs if we do this int main and then
integer arg C and then a character pointer arg V and then an array those are
those two registers right there I probably want to change this into long
because you know rdi is in 64-bit form but an integer is an unsigned 32-bit int.
I don’t like that so I’m just going to put long. I probably should put unsigned but I don’t really
care. Anyway so we’re just going to grab those two things so obviously rdi is probably pretty
easy for you to guess how to use it’s just the number of arguments. In this program we’re going
to use it to control a loop counter that’s going to loop through all incoming arguments.
which is going to be the name of the program in this case it’ll be I think
just main is what I called it which is confusing against the entry point I
admit it but imagine that my main program that sits in the file system is
actually called program or hello or whatever so that’s the number of
arguments in RDI and then RSI notice how it’s a character pointer to an array of
characters that means it’s actually a pointer to a pointer and the reason for
every argument on the command line like for instance if i went back here and i said echo
hello let’s just do without quotes hello you i’ve given it two arguments and so when the program
launches it’s going to receive three total it’s going to receive its own program name at index zero
echo it’s going to receive at index one the first argument hello and it’s going to receive at index
two the second argument as you it prints them both so how does echo know how many arguments i have
strings. Remember argc is the number of arguments so that’s kind of easy but how does it dereference
all of the strings if there could be any number of strings? Well that’s this right here.
This whole symbol argv is a pointer and it points to an array of pointers, of character
pointers. That’s why it’s written like this like an array. So it’s a pointer that points
points to an array.
So like if you go to that location in memory,
then what you will see there for the first eight bytes
is just the address of some other memory location where a string has been stored.
Then if you advance that pointer another eight bytes for it,
you know, in memory, because all pointers are eight bytes or 64 bits,
then again, you’ll see that that value of that next eight bytes
is actually a memory location that points to another string somewhere else.
So these strings could be all over the place,
But the pointers to those strings are contiguous in memory starting with what you were given in RSI.
So it’s a character pointer pointer or an array of character pointers, however you want to imagine that.
Anyway, so we’ll grab those and then I’ll just show you how to use them down further in the code.
For starters, I’m calling on an intro function which just basically prints some stuff.
I have a custom function that I wrote called print null terminated string.
That’s not the point of this video.
I have that explained in other videos a little bit.
So it’s up to you if you want to even care.
Right now I just want to be able to print something.
And then let’s see.
So after we print our welcome message in the intro, then we print another message basically
saying okay now we’re about to start printing all the arguments.
Okay cool.
Nothing complicated at this point.
Then I have another label here with my preferred style of adding a suffix after the function
after the function that I’m currently inside of.
And I’m going to say, all right, this is where I initialize my loop.
This is not a looping video, so I’m going to skim through it kind of.
But I’m basically going to say, let’s start the loop as basically saying
the index of the argument that we’re currently looking at is zero
because we’ll start with zero.
So that means we’ll print like if we were going to, if our program was named Echo,
we would also print Echo itself and not just all the incoming arguments
that the user might have typed.
index zero and then we’re going to use r15 as the current character pointer so r15 its current
character pointer is going to be coming from r13 which was the argv argument so that means
r15 is now going to hold a pointer uh let’s see it’s going to hold
when you have an array and the array is contiguous in memory then the pointer itself that points to
the array is also a pointer to the first item that’s just kind of the way it works like if we
have 10 items and it’s an array then your pointer to that array is also a pointer to the first item
in the array if that makes sense so if r13 was a pointer to an array it’s also a pointer to the
go off to a null terminated string i know that sounds weird you got to get used to double dereferencing
here so all we really need to do to access uh the first pointer to the actual string is take the
array pointer that we have and dereference it one time so remember we’re receiving an argv
a pointer to a pointer or like a you know a double pointer if we dereference it once then we should
terminated string. Anyway, so that’s the initialization part. I’m going to start looking
at the first string here and I’m going to say we’re at index zero. And then here’s the top of
my loop. You can imagine this is a while loop. This is not a while video, but you know, there it is.
And we’re just going to ask first, are we actually done? Do we need to break the loop? I like to do
that at the top of my while loop. And how we’ll do that is we’ll say, all right, R14 is the index
the number of arguments so notice how like right here we grabbed RDI right
into R12 right away so basically I’m saying if the index we’re currently
looking at is greater than or equal to the number of arguments then we’re
actually already done remember if we’re using zero based indexing and you
suppose that you have three items in your array their indexes would be zero
So that means if the size of your array is three, like the count, like the RFC, that
means the last valid index is two.
It’s one less than the size.
You know, it’s one less than the count.
So I’m saying at this point that if we ever reach an index number that is equal to the
size, then we’ve already finished.
We do not need to look at the current item.
So I’m comparing those two registers.
You know, where are we looking at versus what is the count?
You know, what is the index we’re looking at versus the count?
If the index we’re looking at is greater than or equal to the count, then that means we’re done.
I’m going to jump out of the loop to a label called main loop done.
So then, you know, that’s down here.
Basically, we just say goodbye and then we jump to our exit function.
And all that does is it just returns from main with some kind of a success code.
You know, so just you can imagine in C++, it’s just return zero.
So, you know, breaking the loop doesn’t really do anything except end the program and say goodbye.
However, if we did not jump, then the, let’s see if we did not jump, let’s, let’s see if
we did jump, we compared it, we realized that we’re done.
Then it’s going to jump down to the, to the done.
But if we’re not done, execution is going to fall through to the next statement.
So that means we’re going to end up doing something with the current item inside of
our loop.
So what are we going to do?
We’re going to dereference R15.
was your pointer to a pointer it was your double pointer there if we dereference it once then
instead of being a pointer to an array of pointers it’s going to be a pointer to one string one one
character that starts one string so dereferencing it once means you know i put brackets around the
double pointer it’s now dereferenced once that means rdi is going to receive a pointer to one
into my function my function takes two arguments it wants a pointer to a string and it wants
the file descriptor to print to again other videos explain you know printing to standard
output but i’m just going to print the string so this part right here should actually print
the argument and then after we’re done with that uh well maybe i should change this
so that it’s a little bit more clear i’m going to maybe push this down and say
these lines up here actually do something they do the printing by
dereferencing and then here we just sort of increment along the array of pointers
and jump back to the top of the loop so what are we doing here with r14
remember r14 was the index that we’re currently looking at so we we start
looking at index 0 line 83 is going to say let’s next look at index 1 and then
this part right here add 8 to r15 that just basically means remember r15 was
remember r15 was the double pointer the double pointer like i said before it’s looking at an
array of pointers so it’s actually a pointer to a pointer if i increase the memory location that
r15 holds then it’s now looking at the next pointer it’s moving through the array r15 at
that point would no longer be a valid pointer to the original array it’s sort of like a running
pointer it’s kind of like scanning all of the pointers but a pointer is eight bytes so if we’re
a pointer is eight bytes so if we’re just looking at the first pointer and we increase the memory
location that we’re looking at by eight bytes now we’re looking at the second pointer so then on the
next iteration of the loop if we dereference then we’re going to end up dereferencing to the second
string then i just print a little new line here honestly probably should have put that up top
sloppy code i was doing this quickly and then we jump to the top of the loop so then we just
going up to the top of the loop and printing arguments and advancing to the
next pointer. And we just keep going at it.
Let me see if this works. Hopefully I didn’t mess this up while I was screwing
around. All right. So I’m going to do this make run. Okay.
So under the hood inside of my make file,
maybe let’s open the make file real fast just so you can see.
I’m just going to nano it real fast here under the hood.
So when I call the program to run, notice how I’m giving it arguments.
You can see right here on this line, or actually let me get the line numbers up.
You can see on line 48, I am calling my executable, which is named main.
In the make file, I’m using a variable, so don’t worry about that.
But I’m giving it four arguments.
And I’m just saying first arg, second arg, third arg, fourth arg.
So that’s why you see that printed in the previous screen.
screen it’s just going through all the arguments that I gave it it’s saying
first arg second arg third arg fourth arg notice how it knows when to stop
because of the argc that came in on RDI now that the program is built you know
I’ve got my main executable which I named main which I said before was kind
of confusing now that I’ve got it I can just execute it again and give it like
one argument of like hello notice how it prints hello on a line by itself you do
do it again dudes and notice how every argument I give it it just prints it no
matter how many I do I can go a b c d e f g I could probably do this so many
times that I exhaust you know a long integer which is would be a horrible
endeavor but yeah everything that I put on there it just loops through it and
prints it so when you are linking with GCC because you’re probably using a
if you’re just linking with GCC.
GCC makes it really, really easy
to access the command line arguments.
Imagine now instead of just printing these things,
you used them to somehow decide
what your program was gonna do.
Maybe the user will give you a sub command.
Like if you’re a Git user, we say Git status, right?
So the Git says like, oh, you Git launches
and it goes, you want the status of something?
Yeah, sure.
So in your program now,
you could read what the user typed,
figure out a way to parse it and interpret it
have your program’s behavior adjust to whatever the user typed in okay that’s it for this video
the next video I’m going to post is how to do basically exactly the same thing but using pure
assembly without linking against GCC so like LD is going to be the linker just like pure assembly
no extra libraries okay thank you so much for watching this video I hope you learned a little
tell your friends and i’ll see you in the next video
hey everybody thanks for watching this video again from the bottom of my heart i really appreciate it
i do hope you did learn something and have some fun uh if you could do me a please a small little
favor could you please subscribe and follow this channel or these videos or whatever it is you do
on the current social media website that you’re looking at right now it would really mean the
and grow this community so we’ll be able to do more videos, longer videos, better videos,
or just I’ll be able to keep making videos in general. So please do me a kindness and subscribe.
You know, sometimes I’m sleeping in the middle of the night and I just wake up because I know
somebody subscribed or followed. It just wakes me up and I get filled with joy. That’s exactly
what happens every single time. So you could do it as a nice favor to me or you could troll me if
you want to just wake me up in the middle of the night, just subscribe and then I’ll just wake up.
just wake up I promise that’s what will happen also if you look at the middle of
the screen right now you should see a QR code which you can scan in order to go
to the website which I think is also named somewhere at the bottom of this
video and it’ll take you to my main website where you can just kind of like
see all the videos I published and the services and tutorials and things that I
offer and all that good stuff and if you have a suggestion for clarifications or
or errata or just future videos that you want to see please leave a comment or if you just want to
say hey what’s up what’s going on you know just send me a comment whatever i also wake up for
those in the middle of the night i get i wake up in a cold sweat and i’m like it would really it
really mean the world to me i would really appreciate it so again thank you so much for
watching this video and um enjoy the cool music as as i fade into the darkness which is coming for us
Thank you.