Mastering Standard Input, Output, and Error (STDIN, STDOUT, STDERR) in Linux with Yasm Assembly Examples

Mastering Standard Input, Output, and Error (STDIN, STDOUT, STDERR) in Linux with Yasm Assembly Examples

Get a clear, hands-on look at Linux’s standard input (STDIN), output (STDOUT), and error (STDERR) pipes! In this video, we explore how programs communicate using these essential streams, with practical examples in Yasm Assembly (no assembly knowledge needed!). Learn to redirect outputs, handle errors, and read inputs like a pro. Whether you’re a beginner or seasoned coder, this fun demo breaks down the basics of Linux pipes. Subscribe for more coding insights and check out the full tutorial on our site!

Introduction to STDIN, STDOUT, STDERR 00:00:00
Overview of Pipes in Linux 00:00:07
Explanation of File Descriptors 00:01:12
Demonstrating Echo Command 00:01:24
Redirecting Standard Output 00:02:02
C++ Example with cout and cerr 00:02:48
Purpose of Separate Error Pipe 00:03:28
Assembly Program Introduction 00:04:55
Creating Data Section in Yasm 00:05:22
Writing Helper Functions 00:07:37
Printing to Standard Output and Error 00:11:29
Testing Output Redirection 00:12:43
Standard Input Explanation 00:14:54
Creating Stack Buffer for Input 00:16:03
Reading from Standard Input 00:17:28
Piping Input to Program 00:20:54
Handling Null Terminators 00:22:02
Conclusion and Call to Subscribe 00:23:53

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

Hey everybody.

In this video I’m going to talk to you a little bit about standard input, standard output,

and standard error.

Three pipes that every program has in Linux that allow it to just communicate in a very

standard way.

I’m going to show you some example code written in Yasm Assembly, but assembly knowledge is

not necessarily required for this video.

You can just sort of follow along.

Anyway, what is standard input, standard output, and standard error?

Well for starters, every program that gets launched, under the hood, the operating system

will typically attach three pipes to it.

Basically one for standard input, one for standard output, and one for standard error.

the program pretty easily. So let’s see. Oh, I know what to do. There’s an echo command, right?

So here’s the program called echo. When the program launches, it’s going to have three pipes

attached to it, just like I told you before. These pipes also behave as file descriptors,

as if you had opened a file, but their file descriptor numbers are always zero and one and two.

Zero for standard input, one for standard output, and two for standard error. So if I launch the

program it’s going to get those three pipes those three file descriptors and

right away the standard output is going to get attached to the program running

our terminal here well not necessarily the actual terminal but bash under the

hood which is the program that we’re using to interact with the operating

system so basically the program launches and based on this incoming argument that

I give it hello then it’s going to print the string hello right but what it’s

its standard output pipe its standard output file descriptor I can test this

for sure by just sort of doing the command again and then muting its

standard output pipe with this little shell trick I’ll do a arrow or a greater

than angle bracket and I’ll just send the first pipe I’ll do one I’ll send it

to dev null and on Linux dev null is just if you send anything there it just

it’s just totally ignored so if i send uh the pipe labeled number one to just nowhere then notice how

it doesn’t show on the terminal for me right it’s pretty cool let’s go a little bit deeper into this

i just want you to see real fast before i write an example program in assembly what you would

probably end up doing in c plus plus so we usually do something like iostream in germane you know

We’ll say using std cout std c error std and l and so forth.

And then if you actually want to print a message to the user, we’ll say cout this message prints

to std out because that’s what cout does by default.

And then if we do c error, a lot of people haven’t actually seen this and I personally

always forget that it’s even there if you print to see error it prints a message to standard error

why would you want two different pipes that printed messages and one is called output and

one is called error well like i’ve said before in other videos it’s really convenient to be able to

have programs automate other programs for example if you have a program that is launching you know

a second program maybe the second program fails in some way or wants to complain to you in some way

or wants to complain to you in some way, it would usually, if it’s smart,

print the complaint to standard error.

It may not actually use C error because maybe it’s not a C++ program,

but it would print to pipe number two, file descriptor number two, standard error.

And then that way, the program that’s launching it can just sort of ignore messages

that happen on standard output because we can assume all of those messages

are just normal info messages that a human might want to see.

Or maybe you want to record to a log or something somewhere

log or something somewhere and just kind of save it away.

But the error messages are a little bit more important than the regular,

you know, normal messages.

So if you’re automating another program,

then your program probably wants to take standard output and either ignore it or

just kind of send it to a different file.

And then it wants to take standard error and pay more attention to it.

Write it to a log file, save it, maybe check that it’s actually blank.

And if it’s not empty, then maybe alarm bells go off.

Something went wrong.

We have to alert someone or, you know, make a database entry, send an email, whatever.

And yeah, just pipe one and pipe two is how you accomplish that.

So this is what’s happening in C++ when you do that sort of thing.

Okay, so now I would like to write a sample program that just kind of demonstrates this

real fast.

So please bear with me.

I’m going to go really fast for the assembly portion because this is not an assembly video.

to learn more about how to write assembly in the first place than see my other videos.

For now, I’m just going to create a little blank file here.

Let’s see where the heck is my window.

I’m on a multi-window system here.

Okay, so I’m just going to paste a little data section.

This is Yasm assembly.

A little data section.

I’m just going to fill it up with strings.

I’m going to make a string for the introduction.

Hello, the module has started.

A string announcing everything that we’re going to do.

We’re going to begin printing to standard output and standard error,

and then some messages that will go to each.

And then some messages that will go to each and then a standard input string, which we’ll

talk about after the standard output and standard error.

So just a bunch of strings.

I’m going to make a buffer size.

I’m going to make system call codes for reading, writing and exiting.

If you want to know more about system call codes, see my other videos and some file descriptors.

This is exactly what I just talked about.

The file descriptor for standard input is zero for standard output is one for standard

for standard error is two.

And then I’m going to do a system exit code of zero,

which actually doesn’t matter that much,

but I’m going to do it.

So now I’m going to make a, let’s see,

a global,

hmm, make a global.

Oh, did I already make the text section?

Here we go.

So there’s the text section.

So the data section is over now.

So data section is over now.

I’m going to make the tech section.

I’m going to make a global entry point called start.

Again, if you want to know more about assembly programming in general,

see my other videos.

But so this is the entry point of our program.

At the very end, we should probably just program that it exits with success

and test it out real fast.

So basically right now this program does nothing.

Let me just double check.

Clear and make run.

I have a make file under the hood, but this is not a make file video.

If you want to know more about make files, see my other videos.

know more about make files see my other videos but basically it just starts running and then

it just dies right away okay no problem let me actually can i i want to fix that make file

because it’s it’s labeled after like a different project that i was doing let’s do

there’s no need for me to even do this i’m just uh i just can’t help myself okay so there we go

going back to the editor.

We have a program that does nothing.

I’m going to copy paste in a couple of useful functions that I use elsewhere.

Again, this is not an assembly video.

So, so you can look at my code if you want to, if you just kind of want to know how this

works, but not the point of this video.

So I’m not going to spend too much time.

Maybe I’ll just briefly talk about what it does, but not the point of this video.

So the first thing I’m doing is I’m adding a function called print null terminated string

function called print null terminated string just you know it sweeps through a

string or actually it asks another function I made to find out how long the

string is and then it’ll print the string to some file handle that I gave

it like standard output or standard error and you know it calls on this other

function called string length which I just wrote in pure assembly for fun even

though I didn’t need to and it just kind of sweeps through the string until it

finds a zero and then it knows how long the string is and then CRLF just prints

is and then crlf just prints a carriage return new line uh carriage return new line just um

with the same idea with the print null terminated string function and you can see all my strings have

null terminators that’s the dot zero at the very end of it okay so we got those helper functions

uh the next thing that i need to add in here is

do an intro like my growling i used to have a professor who would go

and he would go oh god when something went wrong and i do that all the time even when things are

going right okay so i’m going to paste a little function here called intro and this is not going

to be anything important it’s just going to print a little hello message you know it just uses my

intro string and then just prints it with those other functions i made so that means now my my

I can call intro real fast and then it’ll return when it’s done.

If I just sort of run the program again, you can see after all the build messages,

it’s just printing that the module has started.

Okay, so nothing super important yet.

Now, what I’d like to do is capture some incoming arguments real quick because…

Let’s see standard input.

Well, that’s actually not going to work.

Let’s see what I want to do here.

No, I think that’s part of a different program.

OK, I’m going to call a demo.

I don’t think I need to add that one thing that I was just looking at.

So I’m going to call a function that’s going to be our main demo.

So it’s going to jump down somewhere.

I’ll just create the function down later.

So let’s see.

Where is it?

Standard input.

I’m going to start off by saying this is my standard input function which is this and

is this pop p and then pop r12 and then it returns if you don’t know what a prologue

and epilogue are or why I’m doing pushes and pops just see my other videos but basically

I’m responsible for preserving it.

And I’m going to use the base pointer to help me remember where the stack started.

I’m just going to choose to…

What did I do?

I started the wrong function.

I’m going to do that one later.

Okay, for now, let me go find where that other one is.

Oh, there it is.

Should have double checked.

I’m going way too fast.

I’ll just copy paste this whole thing from my solution.

So I’m going to do standard.

This video is a mess.

Honestly, it’s a mess, but that’s okay.

I’m going to try my best to explain it.

So I have this function standard output standard error and I’m calling it here.

So it should jump right down there as soon as the program starts.

The standard input one is not getting called yet, but we’ll call it at the end of this

video.

print null terminated string function to print a message to standard output.

Remember standard output was just you know pipe one. Standard error is going to

be pipe two. So if I go back here and I say I want to print this matches to that

pipe then it’ll go to standard output just like the echo program was doing

when we looked at it a moment ago. And then next we’re going to print to

Oh, that was just an announcement that we’re going to begin.

So this is the real message that will say this is definitely going to standard output.

And then this other message is going to go to standard error, which is when we when we

looked at C error or pipe number two a moment ago.

So basically, I’m just printing an announcement and then two important messages.

One is going to pipe one and one is going to pipe two for standard output and standard

error.

OK, like really not very complicated at all.

Right.

So if I run this program now, hopefully I didn’t crash it by copy pasting out of order here.

Yeah, there we go.

Clear and make run.

So notice how it says that the messages are going to be printed.

And then notice that both of my messages actually show up on the terminal.

The one that says this message will print to standard output, number one, pipe one.

This message will print to standard error, pipe two.

They both get printed to the terminal because by default, the terminal will just take both of those pipes.

both of those pipes it’ll take one and two standard output and error but I can

use those little redirection tricks to mute one or more of those pipes so I’m

gonna say pipe one which is standard output I’m just gonna redirect that to

dev null to say I don’t want to see standard output if I run it again

notice how the only thing you can see on the string or on the screen is standard

error pipe to file descriptor 2 on the other hand if I redirect file descriptor

descriptor to pipe two to nothing then I should see all the normal messages and not see the error

message notice right here it’s it prints all the regular you know make file stuff and then the

welcome message and then here’s our message that says this is going to be printed to standard output

so notice how the error message is missing so cool if I mute both of those I can do that I can

then nothing gets printed at all because that’s all we really have is standard output and standard

error all right not too bad right that’s the basic idea between redirecting and things you

could also do things like this if I okay this is not part of my plan but suppose I wanted to take

any error message and redirect it to instead of dev null I wanted to redirect it to some kind of

standard error.txt.

Notice how nothing seems to have shown up on the screen, but if I list the directory,

now there’s a text file called standard error that contains the error message.

So you can redirect pipes, you can reattach them if you’re like an elite hacker.

You can do lots of things with them, but that’s as far as I’m going to take it right now.

I’m going to remove that.

Now let’s look at standard input.

How do you send input to the program?

Remember when programs call other programs, they can send each other standard input too.

It’s just that when I launch something on the terminal, I’m just, you know, I’m the

human and so whatever I type or, you know, what command I type is going to go into standard

input if I do it the right way.

So let’s go back to the program here.

Okay, so let’s finish up standard input.

And let’s see the pre-made code that I had here.

I had the prolog and the epilog, right?

Move the base pointer

RBP and R12. Oh, I got to put the

Base pointer back into the stack pointer. Let’s see move

Again, this is not an assembly video. So just try to hang on here. So what I’m gonna do in this video

I thought I was cute when I was making this plan. I know I’m not like that clever, but um, I

Thought hey wouldn’t it be fun instead of having a global

or the BSS section. What if I just made the stack a buffer? This is kind of what you do when you make

a local array in C++. You’re making a buffer on the stack. So this is not a stack pointer video.

So long story short, I’m just going to keep track of where the stack pointer started with this base

pointer. That’s why I have to preserve it there. And then I’m just going to subtract my buffer size

from the stack pointer. And what is the buffer size? I’ve chosen to do a buffer size of about

So that means the user or me, I could send about eight kilobytes, maybe eight kilobytes

or less into standard input and be sure that it’s all actually going to be received by

the program.

And then I’m just going to use R12 to remember where the start of the buffer is, which is

just wherever the stack pointer started.

Because if we subtract and then the data that increases is actually increasing in memory,

but making room on the stack decreased, it’s just the way it works.

There’s going to be another stack video out there.

stack video out there anyway for now I just create a buffer on the stack and

then I’m gonna print a little hello message so I’m gonna print this so just

my message saying hey we’re about to do something from standard input and then

I’m gonna send that to a standard output so the message is gonna go to standard

output but I’m announcing that we’re about to read from standard input

assuming I actually cleaned up correctly let me double check this this should

It should just simply say that it’s going to without crashing.

Okay, looks good.

So then now I’m ready to actually read from standard input.

We’re going to use a system call from this.

If you want more information on system calls, see my other videos.

But basically you just go to the system call codes table,

look up appendix area of whatever textbook you’re using.

And you say, what’s the code to read?

I want the system to read.

what you know i want the system to read so i define that as system read and if you look up

here in my program it’s just call code zero so sys call code zero is to read from somewhere

and then uh where do i want to read from that’s the second argument for the standard

or for the system call i want to read from standard input that’s going to be the number zero

if you recall and then here is a pointer to the first character of wherever i want it to

read into. So it’s going to read from that pipe, but it has to, it has to write the data that it

read somewhere so that I can save it and access it. So R12 is basically going to be a bunch of

free bytes that I created on the stack. So I like, you know, I’m, I like made the stack bigger,

but it’s mostly empty or with junk data. And R12 is just pointing to the first byte that I have

reserved. So, you know, you could imagine maybe you make a global variable in the BSS section up

up at the top, you know, like an eight kilobyte array of bytes, and then just sort of point

it to that. But in my case, I’m just using the stack because I think it’s cooler. So

I tell it, Hey, that’s the first bite on the stack that you want that I want you to start

reading from. And then I give it the buffer size, which we just looked at. And then I

do a system call and then the system now should do all the hard work for me. It’ll look at

the pipe for standard input. It’ll grab all of it. And then it will only grab, you know,

it’ll stop if the input ends before that and then when I’m done I should be able

to actually read from the buffer which is sitting at R12 and print it to the

screen so the next thing I’m gonna copy paste in there is I’m gonna print what

I just read from standard input so this is another call to my function my little

doggy wants to go pee even though he’s completely lying he just went pee so at

wants to go outside and lift his leg and do nothing and then come back in and demand a treat.

I’ll let him do it in a few minutes just in case but trust me he’s lying he’s laid like five times

today. Anyway I sometimes I regret teaching him to growl at me. It’s so cute but like it’s not

cute right now. I don’t know maybe it is. Let me know in the comments. So basically I’m going to

take that R12 buffer that I just wrote to and I’m going to print that directly to standard output

output and this is not really the important part of the video.

So I’m going to do that and then I’m going to kind of clean up here at the end of the

function.

And then maybe I’ll say goodbye.

I think I just added a string for that.

So maybe I’ll say goodbye.

I’ll say goodbye before we end the function and then I’ll actually return.

So let me go here and run the program.

Let’s see, begin.

printed because we didn’t send anything and we also didn’t call that let me call

standard input call stdin and so now it’s actually gonna print basically

nothing oh I didn’t send it anything so it’s just kind of hanging you probably

want to check this sort of situation but that’s that’s not the point of this

video let me show you how to pipe some some stuff into standard input real fast

hello and then just put a little or bar in the shell this will take the output

of echo and instead of printing it to the terminal it’ll attach its standard

output into the standard input of make run pretty cool shell trick so now we

should see the word hello the word hello printed and that’s what it does we have

detected the following stdin and it says like here’s begin that’s just a string

that I had that I print every time and then here’s the string that it actually

And then it ends.

Pretty nice.

I think maybe we could probably do the empty thing if I just started typing here.

And then maybe I hit control D to detach the buffer.

And yeah, that’s what it does.

It sort of prints here and then it ends there.

Didn’t do a new line.

I think it probably doubled it for some reason because I…

Let’s see.

I didn’t plan for this.

Let me see.

plan for this let me see it printed oh because I did I did not null terminate the string so

actually what it did is it uh let’s see if we can do that real fast one more time I’m going to go

one two three four five then I’m going to just disconnect the standard input buffer because the

printing function needs a null terminator to know when to stop there’s not going to be a null

terminator because I just typed and disconnected the uh the input so it’s actually going to just

until it randomly finds a zero and then it’ll stop so if I disconnect it it

that explanation was bunk let me try that one more time I’m gonna go a bunch

of H’s I guess there is a null terminator I disconnect it no no see how

yeah these little symbols there so it does kind of print until it finds a

null terminator but I guess I was confused because it seemed like it

like it printed it twice what’s actually happening is when i type then it’s getting sent to the

terminal which and that’s not part of the program that we just wrote then when i disconnect standard

input then the program finally prints everything that i actually typed until it hits a null

terminator in this case it looks like it seems to have worked but uh if i just do like a couple

sevens and then disconnect probably have to do this a bunch of times before we’ll see those weird

What did I do? Hit enter. That seems to have worked. My dog is stressing me out

but I love him. Alright anyway just trust me on this sometimes it’s hitting the

null terminator in time sometimes it’s not. But I hope by now you understand the

difference between standard input standard output and standard error. Thank

you so much for watching this video that I’m recording and I hope you learned a

little bit of stuff and had a little bit of fun. I’m gonna let my dog lie to me

I’m gonna let my dog lie to me for a second 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.

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 world to me and it’ll help make more videos and grow this community.

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.

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.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply