do you know how 'return' works under the hood? (are you SURE?)

preview_player
Показать описание
Programming is amazing. Computers allow us to do things that otherwise would be impossible. But sometimes, the code that we write feels like MAGIC. How does all of this stuff work?

Let's talk about how return works.

🛒 GREAT BOOKS FOR THE LOWEST LEVEL🛒

🔥🔥🔥 SOCIALS 🔥🔥🔥
Рекомендации по теме
Комментарии
Автор

Note that this does not apply to all architectures but is specific to x86 (and maybe some others).
For example, on Arm, calls ("branch and link" instruction bl/blr) put the return address into a register (x30).
Thus functions must push the return value on the stack themselves before calling another function (functions that do not call other functions do not need to push it as the register containing the return value is never overwritten).
The return on Arm is just a normal branch instruction, but encoded in a different way such that the CPU is aware that it is a return, not just a normal jump to a register (this enables microarchitectural optimizations like a return stack buffer to speed up execution).
I really liked the video though :)
It would be nice if you can talk about out-of-order CPUs at some point since understanding (at least having a rough idea) how modern CPUs work prevents some optimization pitfalls one may fall into when just thinking about a "traditional" Van Neumann Computer.
And it is the gateway drug to the world of microarchitectural optimizations, side channels, and transient execution attacks :D

LolSalat
Автор

Gotta admit that Assembly was very challenging for me, I think the most challenging task in my life, because it feels so alien. However I'm very slowly starting to make sense of it. This is a testiment to perseverance. No matter how difficult you think something is, continue. Take your time, try multiple times, look for different sources, whatever, but don't quit, ever. You'll get there, and after some time you'll look behind yourself and will realise how much you've learned. Thank you for this awesome video and helping come a little bit closer to really understand assembly.

diegocastillo
Автор

Turns out I ACTUALLY did know how they work.

chbrules
Автор

A few things to add.
Floating point values on x86 are returned via the first scalar of xmm0 register.
In general the way data is transferred between caller and callee is defined by what's called "Calling Conventions". There are a bunch, and they are determined by the the hardware architecture and the operating system, among other things. Fascinating stuff really.

yuriiklopovsky
Автор

Great one. It is easy to forget this when not thinking about it directly and remembering this helps greatly in reverse engineering efforts.

mytechnotalent
Автор

Basic understanding of assembly is important when using any language that compiles directly to assembly. A lot of programmers, even good ones, don't have a clue as to how some of this stuff works. My basic recommendation is to learn to read some assembly by taking a peek at the generated output of a simple program. Look up each instruction one at a time and work out what is happening. It is amazing to me how few programmers don't know some of this stuff.

dougpark
Автор

Do a video about stack unwinding on ARM next. I had a FreeRTOS fw that was running on ARM, and would dump the contents of the stack into the UART. We used this to reproduce the call stack. It was an interesting task and I learned a lot. Could honestly be a direct follow-up to this video.

Sonyim
Автор

The calling convention (stdcall, fastcall, cdecl) also controls how arguments are passed to functions and who's responsible for cleaning up the stack after returning

stacklysm
Автор

Sick video, wish you made it before my compilation exam lol
Thanks sharing all this quality content !

AA-vfvz
Автор

I actually knew this! Proud of myself.

Avighna
Автор

I absolutely love low level stuff. It's sad that we only learn the basics of ARM and x86 at uni. Great video. (and yes, I was sure I knew how it worked :P)

akoskulcsar
Автор

Read the title, but have not yet watched the video...
It pops a value off the stack and writes that value to the instruction pointer. In the case the return statement is paired with a value, IIRC, the value is stored in memory and a specific register/pointer/flag is set to indicate there was a value returned from the subroutine. In general, at least; different architectures might handle things a little differently.

After watching the video...
I was more or less correct. What I referred as "the instruction pointer" is sometimes a counter in different architectures, but I covered that at the end with the "in general..." bit. My explanation of the returned value was vague/broad because it's been a while since I've dealt with low level code. Good to freshen up every so often.

luketurner
Автор

before watching this video i didnt actually now what "return" did, but after watching it, i now know that i dont know what it does

zzzf
Автор

Would love to see some kind of reverse engineering series in which you go step by step, reversing a real-life application and explain every difficulty that you come across.

kvbc
Автор

also interesting (and useless) fact: when returning a struct from a C function (that's not gonna fit into 32/64-bit eax/rax register) a compiler allocates the struct on the caller stack and passes the pointer to it as an extra hidden argument to the called function (callee), which is also what one would typically do in C when wanting a function to "return" multiple values. On asm level both do the same thing.

krztsztofdziub
Автор

Definitely, one of your best, easy to follow but quite intense videeos!

geigenunterricht
Автор

Out of love and interest for a specific game I dove deep into it's assembly code using debuggers, even though I had no previous knowledge about assembly. I learned so many things just by observing which was a wonderful and fun task, and it's nice to see that these things are actually universal at least for x86.

Mystixor
Автор

Oooh. I know this one. Its the function epilogue. Functions get compiled into some bits and the function calling conventions have a prologue that stuffs the current program counter pushed to the stack. Return just pops that value back when the function returns. This is why recursive function calls can overrun the stack

kayakMike
Автор

I literally had to write about this in a final-exam yesterday about what CALL and RET statement does in 8086 assembly

opppjux
Автор

One thing I'd like to pointt out is that if you see something like "RET 8" in assembly, it is NOT the same as "return 8;" in C. In assembly, a number after RET tells the CPU how much to adjust the stack before/after returning (I forget which)

williamdrum