0

I'm currently reading "Programming: Principles and Practice using C++", and the author mentioned that writing the definition of a member function within the class definition can make a function inline. I wasn't entirely sure what that meant, so I looked on https://www.geeksforgeeks.org/inline-functions-cpp/ for a more concrete understanding. I can't seem to understand what "instruction" means in the context of this sentence:

When the program executes the function call instruction the CPU stores the memory address of the instruction following the function call.

I googled, and it looks like call instructions are just passing control another part of the program or another application. If that's what they mean, shouldn't they say that "the CPU stores the memory address of the call instruction of the function call"?

This question may sound weird or nit-picky, but I am new to CS and really want to get a solid understanding of CS.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Sebastien
  • 23
  • 3
  • 3
    Be careful: the C++ definition of "inline" (which does happen when a function definition is inside a class definition) and the compiler optimization of "inlining a function" (which that article discusses) are nearly unrelated things. The article somewhat talks about the difference, but doesn't do a very good job of explaining it, in my opinion. – aschepler Aug 24 '18 at 03:13
  • Another couple good search terms to follow up on this would be the key phrases "program counter" and "call stack", in addition to "x86 call instruction" below. The search phrases I'm suggesting apply universally to all flavors of assembly, and not just x86. – Patrick Roberts Aug 24 '18 at 03:15
  • 3
    They're talking about the x86 `call` instruction. See [Intel's instruction-set reference manual entry for it](http://felixcloutier.com/x86/CALL.html). – Peter Cordes Aug 24 '18 at 03:51
  • @aschepler Oh, I didn't know there were two different definitions for inlining, which could explain why it was a little hard to follow. I currently only want to know what exactly is a C++ definition of "inlining". I will try searching for that instead. – Sebastien Aug 27 '18 at 01:09
  • @Peter Cordes, I will look into that link. I partially feel like deciphering what x86 call instruction is a beyond my current level since I'm still new to CS. But I find that I'm too curious to just ignore and move on. – Sebastien Aug 27 '18 at 01:10
  • Only the `call rel32` (direct near call) form is relevant. All the stuff about call gates and far calls is totally irrelevant, but most of the text and pseudocode in the documentation are about that (because they're far more complicated than just pushing a return address and jumping). – Peter Cordes Aug 27 '18 at 02:38

4 Answers4

3

They do in fact mean that the memory address of the instruction following the function call is stored. This is because of the way instructions work at the machine code level. After the function call is completed the program needs a way to get back to where it was. It does this through a jump instruction to the stored memory address which causes execution to jump to that instruction. If the memory address pointed to the function call, it would loop forever.

  • 1
    In normal asm terminology, we'd say that `call foo` pushes a *return address* onto the stack. And that `ret` pops it off (into the program counter / instruction pointer). So yes, `call` needs to push the return address where execution should resume, not its own address. That address is the byte following the last byte of the `call` instruction, i.e. the start of the next instruction. – Peter Cordes Aug 24 '18 at 03:54
  • I relatively understand the logic behind call and return. That is I get that the CALL instructions allows the program to jump to the address inside the operand of the call instruction as SoronellHaetir pointed out. And reading everyone's response I realize that this Call instruction is pertaining to machine code (assembly language). However, I still seem to not understand what exactly are instructions. Are they the equivalents of statements/expressions in standard C++ programming? – Sebastien Aug 27 '18 at 01:27
  • Processors are only able to understand very basic operations such as moving an integer to another memory location or adding two integers together. Instructions are basically commands that are sent to the processor telling it to do these basic operations. They essentially instruct the processor what to do at the most basic level. Statements/expressions may compile down to as little as one instruction or as many as are needed to achieve that statement/expression depending on how complex it is. – NarwhalFire Aug 28 '18 at 18:21
1

First of all, the page you link to is talking about the behaviour on a particular class of systems. It isn't describing Standard C++.

The page is talking about what happens in assembly language that could be generated by a C++ compiler. By "function call instruction" it means the assembly language (or machine code) instruction which performs the function call. In x86 syntax that instruction is call. Example.

You could find out more information about this by searching "x86 call instruction" or similar terms.

The address being stored , which is usually called the return address, is the address of the next instruction after the call. When execution of the function reaches the ret assembly instruction, execution jumps to the return address.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • In other words, can I think of instructions as a statement that calls/goes to whatever function we want by using an address of a function as the operand of the instruction? – Sebastien Aug 27 '18 at 01:34
  • @davepleteau that's what the `call` assembly instruction does, yes – M.M Aug 27 '18 at 01:44
1

No, what it is saying (and this is particular to x86 chips, others may do it differently) is that the CPU stores the address of the instruction following the call (on top of the stack) and then jumps to the address that is the operand of the call instruction. When the called function executes a 'ret' instruction that stored address is read and execution jumps to that point.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • ... assuming that the stack pointer is pointing to the return address when the function runs `ret`. There's no magic to make this happen. `ret` is basically a fancy name for `pop rip`, and beginners often get this wrong so it's worth pointing out. – Peter Cordes Aug 24 '18 at 03:49
1

When an x86 CALL instruction is executed, the contents of program counter i.e. address of instruction following CALL, are stored in the stack and the program control is transferred to subroutine.

(x86's program-counter register (IP / EIP / RIP) isn't normally directly accessible, but it's defined as pointing to the next instruction while the current one is executing.)

On completing the execution of the subroutine, the RET instruction is executed which loads back the stack contents i.e. address of the instruction following CALL instruction, into the program counter.

Thus execution is resumed in the caller at the instruction following the call

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Welcome to Stack Overflow :) I made some minor edits to your answer to highlight the important stuff even more, and clean up the English. – Peter Cordes Aug 24 '18 at 04:02