Demystifying x86-64 Program Segments: Stack, Heap, and More

Demystifying x86-64 Program Segments: Stack, Heap, and More

Join us for a clear, engaging look at x86-64 program segments! We break down the text, data, and BSS sections, explore stack vs. heap memory, and show a real stack overflow in C++. Learn why segmentation faults happen, how virtual memory works, and tips to avoid crashes. Whether you’re new to assembly or leveling up your coding skills, this video is packed with insights to boost your understanding of low-level programming. Subscribe for more coding deep dives!

Introduction to x86-64 program segments 00:00:01
Understanding segmentation faults 00:00:12
Importance of segments in assembly 00:00:32
Overview of assembly program structure 00:01:09
Defining segments in Yasm assembly 00:01:49
Data section: Initialized global variables 00:02:20
BSS section: Uninitialized variables 00:03:23
Text section: Code and functions 00:03:59
Global and extern function declarations 00:04:41
Stack: Local variables and return addresses 00:07:11
Stack overflow example in C++ 00:08:48
Heap: Dynamic memory allocation 00:11:31
Stack vs heap memory growth 00:11:56
Virtual memory and memory allocation 00:14:00
Demonstrating memory overflow with heap allocation 00:16:59
Summary of segments and their purposes 00:17:59
Closing remarks and call to subscribe 00:18:47

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

Hi there!

Let’s talk about x86-64 programs and their segments and the purpose of the segments.

Probably when you’ve been programming in the past you’ve seen segmentation fault errors.

If you’ve accidentally crossed the bounds of some appropriate memory location, if you

have an array and you try to index it way outside of bounds or something, you might

have seen a segfault.

SegFaults basically come from the idea that you have crossed a segment boundary.

Segments used to be really, really important.

They’re a little bit less important now that we have virtual memory.

I’ll just talk a little bit about them.

I’m going to be discussing this from the perspective of an assembly program,

just because even in higher level languages,

your languages will typically be compiled down to assembly

first before they actually hit machine code and your actual executable binary.

So if you’re not interested in Yasm Assembly,

Yasm assembly I think this could still be worth it for you to watch because

you’ll be able to see the different segments and just kind of get a better

understanding of what they are okay so I’m gonna actually write a very very

very quick program in assembly it’s not gonna really do anything I just want you

to show I just want you to see the segments that are involved so for

starters let’s just pretend that I’m writing a an assembly program here we’ll

This is a comment just so you know what I’m about to type.

Perhaps actually this is not the best editor.

I don’t know why I pulled this up.

Let me get Gene here.

It’s a little bit better.

Gene.

There we go.

Maybe I’ll save it somewhere.

I’ll say segments assembly.

And then now the comment gets highlighted.

Okay.

So in assembly in the ASM assembly,

we denote various segments by using the section keywords.

keywords so we’ll say section and then dot something indicating the type of segment that we’re

defining so section text and then up here we’ll have another one section dot bss and you know if

you already program assembly you know that somewhere in here is where the code goes right

between these sections so just a quick recap of what the data section is it just is where you

can name and initialize at the same time at the very top.

Globals are not great, but sometimes you want to do that in assembly, depending.

It’s better if you stick all your variables on the stack.

Like if they’re a local variable, it’s a little bit better.

Think of higher level languages.

You typically want to avoid global variables if you can possibly avoid them and make

everything else a local variable or a member variable.

So that means somewhere else other than data, probably the stack, but or the heap.

Anyway, you know, this is like the basic pattern.

We’ll say, you know, my variable and then we’ll decide to say what data size it is.

In this case, it’s DB for one byte of data.

You could put a, I think DD in there or a DW for a word.

Sorry, sorry, DW would be for a word.

And then I think DD would be a double and then DQ would definitely be a quad word.

So here quad word is eight bytes.

And then I can sort of initialize it to some number.

some number and now I have a global variable so not like a huge deal the BSS section is basically

where you have uninitialized variables but there you can make huge amounts of variables you can

make an array of variables so if I say my array something like that I could put resource queue

to say I want the type of one item to be a quad word so you know eight bytes per item and then I

could just say I want you know a hundred thousand items or something and I’ll

double check that after I stop recording this video and correct it if I’m wrong

it’s been a while since I actually typed BSS here and then in the text section

this is where you put code and functions and things you typically want to have at

least one entry point somewhere you know if you want to make like if you want to

make this the entry point of your entire program you’ll probably do global main

main and then this assumes that you use the GCC libraries and just sort of return from the label

sort of makes it a function assuming you didn’t ruin any of the other data.

So those are the three sections that we can start off looking at the data section,

the BSS section, and the tech section. It’s important to note that besides marking functions

as global so that they’re accessible to other segments or other modules, we also mark

We also mark functions and labels that we would like to access that are in other modules.

So if we’re using the GCC libraries, we could say something like global printf,

and then right away we’re able to call the printf function.

Or say if you have another function in another module,

like a different source code file that’s compiled somewhere else,

we could say, you know, my other function.

Something like that.

Just mark it as global.

Or sorry, not global.

Extern.

Xtern. Global is when you have the function in the current module and you want it to be available to other modules.

Xtern is when the function or label is in another module and it’s already been made available to you,

but you want your current module to know that it can access it for the purposes of assembling the program.

So that means inside of here we could do something like call.

We could say, let’s call my other function.

my other function that will work if the other function is actually a function

with a return statement and it respects the ABI you know it pushes registers that

it’s going to modify if they’re callie saved if it’s not another function maybe

we’ll say extern my other jump point so like not a proper function but just

something that you might want to jump to then instead of using call we would use

jump, you know, and so forth. So those are the basic sections. Let’s see, for the BSS,

I definitely talked about token size and count. And then there’s resource B, resource W, resource

D, resource Q for the different sizes. So basically just take all the different sizes you could put

in the regular data section and assume that that could be popped on to the end of RES inside of

the BSS section. If you’re interested, this is a segments video, not an assembly video.

assembly video um another segment uh another segment that we’re not showing here in this

source code is the actual stack probably i guess the best way that i could show it is

i don’t know by messing around with the stack pointer increase uh

oh rsp why did i think it was the instruction pointer we could increase the stack pointer and

stack pointer and then decrease the stack pointer.

It doesn’t really help a whole lot.

But in another video, I’m gonna talk more in depth

about what the stack is and how to use it and such.

But just keep in mind that the stack

is where local variables are stored

and you can use it in assembly and C++

and other higher level languages.

You can even make virtual stacks

in any type of program almost

to just sort of have a stack like structure.

But in C++, if you make any local variable,

any local variable, then it’s usually going on the stack.

And the stack tends to have a fixed size.

And so if you sort of put too much data on the stack,

you risk a stack overflow, which will crash your program.

Besides local variables, the stack will hold other information that the current scope needs,

like its return address.

So when we make a function and then let’s say we call another function inside of it,

actually just up here even when we call another function on line 22 the stack will receive the

return address of where we currently are so that later when we return from the other function you

know the program knows where to jump back and forth it’s actually under the hood just jump

instructions when you do call it’s it’s not it’s not like a special thing it’s just jumping to

another location and then pushing the return address on the call stack so that’s other stuff

other stuff that the stack holds, which means if you have like an endless or like a infinite

recursion happening in your function where just a function calls itself over and over

and over again, or you have some complicated call graph and you end up calling too many

functions without ever returning, you could overflow the stack.

So that’s not good.

Let me show you a quick example that I’m going to make for you real fast.

Oh shoot.

Did I actually make this?

Where is the, it’s on the desktop.

Okay, I guess I’m going to make more on the desktop.

Let’s do a stack overflow.

Let me do desktop here.

Let’s do stack overflow.

That’s CBP.

I’m just going to make a quick program.

In C++, that doesn’t really do anything except overflow the stack.

So I just want you to know the stack can overflow.

I’ll make a function called F.

And F just calls itself.

calls itself. So that’s going to be an infinite recursion.

And that means, you know, every single time F calls itself,

the return address of like line five is going to get pushed onto the stack again.

So it’s just going to get pushed and pushed and pushed and pushed.

The stack will overflow faster if I had local variables because every scope that

gets called, even if it’s the same function name, it’ll have its own allocation on

the stack. So if I just sort of like call this from main and then I’ll just need

and then I’ll just need to make a little uh a little make file that just kind of compiles

I don’t really even need to make a make file I could do a build script but I’m going to do it

anyway we’ll say g plus plus standard equals c plus plus 23 show all warnings show pedantic

the input file will be stack overflow cpp and then the output file will be main

main and then assuming that succeeds I’ll just run main so this is like not a make

file video I have other videos for make files let’s see let me get to the

desktop if I run the make file with just the word make you should see a stack

overflow we should also see a warning about the fact that there’s infinite

That’s funny, I must have done something wrong or different because on a different computer

not too long ago I did the same thing and I saw a warning.

Okay, well thanks for not warning me.

But anyway, you can see that we have a segmentation fault here because the stack overflowed.

We just made a stack that was too huge.

This is a reminder that the stack is not necessarily as dynamic as the heap.

You can definitely overflow it.

It’s not really meant to store gigantic amounts of data.

What am I talking about when I say the heap though?

So just keep in mind that whenever you allocate dynamic data,

well, maybe, well, what do you think?

Maybe, maybe inside of, instead of calling F, let’s call G.

The heap is where you allocate dynamic data.

So anytime you use the malloc operator in C or the new allocator in C++,

you’re creating like a dynamic allocation of data.

I’ll do a new integer and then I’ll do like a thousand integers so this is

basically going to allocate a thousand new integers in the heap which is a

segment that is right up against the stack I should mention also that the

stack it’s important the stack its memory locations go down as the stack

grows keep that in mind because typically when you when you imagine a

stack I’ll make more videos in the future so you can visualize the stack better but most of you who

know what a stack is already you imagine that the stack grows upward visually right but in your

computer the memory locations of the stack grow downward so if I add something to the stack then

the new stack head pointer is actually going to be a lesser address and the reason for that is the

stack and the heap they grow in the same direction towards the same unallocated space we’ll call that

We’ll call that space the unallocated memory space or the unmapped memory space.

And it’s just, you know, a segment stack in the heap.

And then there’s the unallocated space that they grow towards each other.

If they ever meet, then your program is out of memory and it’ll crash.

But the heap actually can be dynamically allocated to store tons of RAM.

I’m probably about to crash this computer.

So maybe this video won’t finish recording.

recording so maybe I’ll try to crash this at the very end I just wanted you to

see let me let me do this I’ll say while true we’ll just allocate a new integer

this is kind of bad form because when you allocate you know a new variable

somewhere you want to have access to it after the allocation you would usually

send that into a pointer you’d say like you know integer pointer P equals new

in something like that right but in this case I don’t really care I’m not gonna

that memory i just want you to see how fast the memory can grow when we did the stack overflow

seemed like the program died pretty quickly but here we’re going to be able to see the memory

boom pretty pretty big before the whole computer just starts to you know fall to its knees

so i’m going to do a call to g here and then i won’t actually run this until

i’m ready to crash this whole video let’s see what else can i say

Oh, the reason that the heap can grow so much larger than the stack is our programs now in the modern era, they use virtual memory.

So it’s not like when we allocate, let’s say we’re accessing a memory location via a pointer inside of our program.

It’s not that the pointer has the absolute memory location through the whole system.

Like it doesn’t, it’s not able to name locations outside of the current program.

Every program sees its own start memory location as just zero.

And then under the hood, there are some extra tricks so that when you try to access a memory location,

let’s say memory location 100, because you’ve made, I don’t know, this many integers or whatever.

Then under the hood, the computer will know what is the start offset of the program’s memory.

So maybe the start offset is 1000.

It’s like totally unrealistic, but just pretend.

The start offset is 1000.

1000 then that means if it’s trying to access a pointer with memory location 100 it just gets added to the offset the virtual offset

So it’ll be a thousand and 100 is the real you know physical memory location or at least at that point

It’ll probably go to the paging system, but that’s that’s another video

So just know that it’s virtual which means the program thinks it has the full range of of the 64 bit memory address space

Even if you don’t even have that much memory on your computer, which there’s no way there’s no way you have so much memory

there’s no way you have so much memory that it’s going to overflow or even meet

64 bits at all but the program thinks it can so it’s just going to grow and grow

and grow until you actually run out of physical memory and then eventually

probably your program is going to start going to the page file or to the swap

file and then when you run out of that then your whole computer probably is

going to start crashing to be honest it’ll probably start crashing as soon as

it hits the swap file because at that point none of the other programs really

None of the other programs really have enough leftover memory to to breathe to do extra

allocations and things so everything’s going to start slowing down it’s going to be pretty bad

and well i think that’s all i really need to say this is not supposed to be a really long video

let me uh let me show you this crasher i’m going to say goodbye now thank you so much for watching

the video i hope you learned a little bit and had some fun too and and that way i’ve already said

if it actually crashes the computer. So I’m going to open up this and then I’m going to do maybe

HTOP so that I can see memory. So if you kind of like look at HTOP real fast,

this is just a Linux command line tool that you can install. It’s pretty cool.

What the heck’s going on here? Oh, that’s my recorder. You can see here’s the memory allocation.

So I’m using two gigs of eight gigs on this virtual machine and then I’m not using any swap

space which means I have not exhausted all my memory and and I have not been forced to go to

the disk for like additional memory but in a second we’ll see that will probably change

so I’m going to do make just to run that it looks like it’s stuck but if you keep looking at the

memory allocation oh it already hit eight gigs now it’s into the swap already probably

The out of memory killer, the OOM, successfully killed the program.

Thank goodness.

Or the whole computer would have been down.

I always forget that that’s going to happen lately.

But you can see it spiked, right?

It went right up to the full physical memory allocation of 7.75 gigs.

And then the swap file went all the way up to 2 gigs.

You can see that the swap file still has about 700 megs inside of it.

That just means that there’s memory that isn’t really being accessed.

the operating system doesn’t feel like it’s necessary to pull it back out of swap and put

it into RAM but I wonder if the video skipped when I did that or stuttered or anything I’m

interested to find out now okay so that’s the end of this video I hope you have a decent basic

understanding of segments and then you know like the segments and their purpose you know the heap

and the stack they grow together the heap can dynamically allocate to grow bigger notice how it

Whereas the stack will crash a lot faster.

If the stack and the heap meet, then you’ve ran out of memory.

At that point, you know, you probably want to like resize the heap or the stack just crashes.

And then we got the text section of the program and the data section and the BSS section of the program.

And these sections are a little bit less relevant in the modern era because we have, you know, virtual memory and stuff.

That definitely means you have tried to access outside of your segment and it’s a no go.

Okay.

Thank you for watching this video.

I will see you at a later date and time.

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

as 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.

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 you could troll me if you want to just wake me up in the middle

And I just subscribe and then I’ll 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

and uh if you have a suggestion for uh uh clarifications 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

Enjoy the cool music as I fade into the darkness which is coming for us all.

Thank you.

Comments

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

Leave a Reply