consider the function
int fun(){
int I;
}
Now is fun a pointer to memory or just an alias for memory location.
The compiler will often just inline a simple function, so something like that might be neither. But otherwise, it is actually a series of instructions. for each function call, the compiler will put a series of instructions that save the current registers on the stack, then jump to the memory location corresponding to that function name, then popping any parameters into registers, and including a ret (return) call at the end which will restore the stack and pointer to the next instruction.
it's an alias, like a static array is. It resolves to an address but unlike a pointer it does not store the address.
Related
I'm trying to create a function that creates an string in RAM of a 16 bit microcontroller.
The function prototype is like this
char CID_Str[12] GetContactID(char Qual,long Event,char Partition,char Zone);
The function should return a little string created with the input parameters.
I never do it a function like this before.
I don't need help with the code inside the function.
I need to know how should I declare the returning parameter (Buffer) because the CCS compiler doesn't like that prototype.
Arrays can be returned as a pointer to the array element type. The returned pointer would be the address of the first element in the array (or memory region). In your case:
char *GetContactID(char Qual,long Event,char Partition,char Zone);
And to your comment:
I just created a buffer inside the variable like this char ContactID[12]; then at the end of the function i have a return ContactID;
Be sure not to return stack addresses (e.g. local variable address). Such an address is only valid within the scope of the function and becomes an invalid (dangling) pointer if returned to the caller. Main options are:
Allocate dynamic memory in the function and return that as the function return value or in an output parameter. Caller is responsible for freeing the memory.
Caller passes in a memory address.
Use static memory.
The first two are the usual cases.
Update: I missed the fact that you are running on a microcontroller. In that case, static memory may be more appropriate as such systems tend not to want the overhead and complexity of dynamic allocations.
I'm learning C and currently learn about pointers. I understand the principle of storing the address of a byte in memory as a variable, which makes it possible to get the byte from memory and write to the memory address.
However, I don't understand where the address of a pointer is stored. Let's say the value of a pointer (the address of a byte in memory) is stored somewhere in memory - how can the program know where the pointer is stored? Wouldn't that need a pointer for a pointer resulting in endless pointers for pointers for pointers... ?
UPDATE
The actual question is: "How does the compiler assign memory addresses to variables". And I found this question which points out this topic.
Thanks to everybody who's answered.
This is an implementation detail, but...
Not all addresses are stored in memory. The processor also has registers, which can be used to store addresses. There are only a handful of registers which can be used this way, maybe 16 or 32, compared to the billions of bytes you can store in memory.
Variables in registers
Some variables will get stored in registers. If you need to quickly add up some numbers, for example, the compiler might use, e.g., %eax (which is a register on x86) to accumulate the result. If optimizations are enabled, it is quite common for variables to exist only in registers. Of course, only a few variables can be in registers at any given time, so most variables will need to get written to memory at some point.
If a variable is saved to memory because there aren't enough registers, it is called "spilling". Compilers work very hard to avoid register spilling.
int func()
{
int x = 3;
return x;
// x will probably just be stored in %eax, instead of memory
}
Variables on the stack
Commonly, one register points to a special region called the "stack". So a pointer used by a function may be stored on the stack, and the address of that pointer can be calculated by doing pointer arithmetic on the stack pointer. The stack pointer doesn't have an address because it's a register, and registers don't have addresses.
void func()
{
int x = 3; // address could be "stack pointer + 8" or something like that
}
The compiler chooses the layout of the stack, giving each function a "stack frame" large enough to hold all of that function's variables. If optimization is disabled, variables will usually each get their own slot in the stack frame. With optimization enabled, slots will be reused, shared, or optimized out altogether.
Variables at fixed addresses
Another alternative is to store data at a fixed location, e.g., "address 100".
// global variable... could be stored at a fixed location, such as address 100
int x = 3;
int get_x()
{
return x; // returns the contents of address 100
}
This is actually not uncommon. Remember, that "address 100" doesn't correspond to RAM, necessarily—it is actually a virtual address referring to part of your program's virtual address space. Virtual memory allows multiple programs to all use "address 100", and that address will correspond to a different chunk of physical memory in each running program.
Absolute addresses can also be used on systems without virtual memory, or for programs which don't use virtual memory: bootloaders, operating system kernels, and software for embedded systems may use fixed addresses without virtual memory.
An absolute address is specified by the compiler by putting a "hole" in the machine code, called a relocation.
int get_x()
{
return x; // returns the contents of address ???
// Relocation: please put the address of "x" here
}
The linker then chooses the address for x, and places the address in the machine code for get_x().
Variables relative to the program counter
Yet another alternative is to store data at a location relative to the code that's being executed.
// global variable... could be stored at address 100
int x = 3;
int get_x()
{
// this instruction might appear at address 75
return x; // returns the contents of this address + 25
}
Shared libraries almost always use this technique, which allows the shared library to be loaded at whatever address is available in a program's address space. Unlike programs, shared libraries can't pick their address, because another shared library might pick the same address. Programs can also use this technique, and this is called a "position-independent executable". Programs will be position-independent on systems which lack virtual memory, or to provide additional security on systems with virtual memory, since it makes it harder to write shell code.
Just like with absolute addresses, the compiler will put a "hole" in the machine code and ask the linker to fill it in.
int get_x()
{
return x; // return the contents of here + ???
// Relocation: put the relative address of x here
}
A variable that is a pointer is still a variable, and acts like any other variable. The compiler knows where the variable is located and how to access its value. It is just that the value happens to be a memory address, that's all.
The pointer is just a variable. The only difference between this and, e.g. a long variable is that we know that what is stored in a pointer variable is a memory address instead of an integer.
Therefore, you can find the address of a pointer variable by the same way as you can find the address of any other variable. If you store this address in some other variable, this one will also have an address, of course.
You confusion seems to originate from the fact that the pointer (i.e. a variable address) can in its turn be stored. But it does not have to be stored anywhere (you only do it when you for some reason need this address). From the point of view of your program, any variable is more or less a named memory location. So the "pointer to the variable" is a named memory location that contains the value that is supposed to "point" to another memory location, hence the name "pointer".
Let's say the value of a pointer (the address of a byte in memory) is stored somewhere in memory
The address of a byte that you allocated, say like this
char ch = 'a';
is referenced by the compiler in the symbol table with the right offset. At run time, the instructions generated by the compiler will use this offset for moving it to from the primary memory to a register for some operation on it.
A pointer, in the sense you're asking, is not stored anywhere, it's just a type when you refer to a variable's address, unless you explicitly create a pointer variable to store it like this
&ch; // address of ch not stored anywhere
char *p = &ch; // now the address of ch is stored in p
Thus there's no recursion concept here.
From the compilers perspective, whether u declare a pointer or a general variable is just a memory space.When you declare a variable a certain block of memory is allocated to the variable.
The variable can be any either a general variable or a pointer.
So ultimately we have a variables (even pointers are variables only) and they have a memory location.
#include <stdio.h>
#include <stdlib.h>
int (*fptr1)(int);
int square(int num){
return num*num;
}
void main(){
fptr1 = □
printf("%d\n",fptr1(5));
}
Can someone briefly explain what happens in stack when we call a function pointer? What is the difference between calling a function directly in main() and calling it by function pointer in C language by the means of physical memory and process?
I tried to understand what happens in memory when we call a function with function pointer but it is not enough to me.
When we call a function by pointer, does pointer have this function's location at code space?
When called function is running is it same as normally called function in main()?
What is the difference of calling function directly or using function pointer when code is running in a pipelined branch predictive processor?
The best way to answer this is to look at the disassembly (slightly modified sample):
fptr1 = □
int result1 = fptr1(5);
int result2 = square(5);
Results in this x64 asm:
fptr1 = □
000000013FA31A61 lea rax,[square (013FA31037h)]
000000013FA31A68 mov qword ptr [fptr1 (013FA40290h)],rax
int result1 = fptr1(5);
000000013FA31A6F mov ecx,5
000000013FA31A74 call qword ptr [fptr1 (013FA40290h)]
000000013FA31A7A mov dword ptr [result1],eax
int result2 = square(5);
000000013FA31A7E mov ecx,5
000000013FA31A83 call square (013FA31037h)
000000013FA31A88 mov dword ptr [result2],eax
As you can see the assembly is virtually identical between calling the function directly and via a pointer. In both cases the CPU needs to have access to the location where the code is located and call it. The direct call has the benefit of not having to dereference the pointer (as the offset will be baked into the assembly).
Yes, you can see in the assignment of the function pointer, that
it stores the code address of the 'square' function.
From a stack
setup/tear down: Yes. From a performance perspective, there is a
slight difference as noted above.
There are no branches, so there is no difference here.
Edit: If we were to interject branches into the above sample, it wouldn't take very long to exhaust the interesting scenarios, so I will address them here:
In the case where we have a branch before loading (or assignment) of the function pointer, for example (in pseudo assembly):
branch zero foobar
lea square
call ptr
Then we could have a difference. Assume that the pipeline chose to load and start processing the instructions at foobar, then when it realized that we weren't actually going to take that branch, it would have to stall in order to load the function pointer, and dereference it. If we were just calling a know address, then there would not be a stall.
Case two:
lea square
branch zero foobar
call ptr
In this case there wouldn't be any difference between direct calls vs through a function pointer, as everything we need is already know if the processor starts executing down the wrong path and then resets to start executing the call.
The third scenario is when the branch follows the call, and that is obviously not very interesting from a pipeline perspective as we've already executed the subroutine.
So to fully re-answer question 3, I would say Yes, there is a difference. But then the real question is whether or not the compiler/optimizer is smart enough to move the branch after the function pointer assignment, so it falls into case 2 and not case 1.
The pointer to function contains the address of the start of the function in the text segment of the program.
Once called, the function runs identically whether it is called directly or by a pointer to function.
I'm not sure. Often, there won't be much difference; the pointer to function doesn't change very often, if at all (e.g. because you loaded a shared library dynamically, so you have to use a pointer to function to call the function).
What is the difference between calling a function directly in main() and calling it by function pointer?
The only difference is possibly an extra memory reference to fetch the function pointer from memory.
Yes
Absolutely
No difference
Calling a function through a function pointer is just a convenience; and makes it possible to pass a function as a parameter to another function. See for example, qsort()
There's no difference between calling a function by its name and calling it through a function pointer. The purpose of function pointers is so that you can call a function that's specified somewhere else. For instance, the qsort() function takes a function pointer as an argument that it calls to determine how to order the elements of the array, rather than having only one comparison method.
I was just looking into the memory allocation of a program in C. I know that all the global and static variables are stored in a heap. Also, the stack stores all the function calls. I do have one doubt here though. Say I am calling the following function:
int ret;
int num = 10;
int arr[3] = {1,2,3};
int *ptr = &arr[0];
ret = giveNumber(num, ptr);
Here, I read that the parameters of the function call giveNumer() would also be stored in the same stack. But in what order will they be stored? If I popped the top of stack, which parameter will be popped first, num or ptr?
I know that all the global and static variables are stored in a heap.
No, thats not true.
As per the standard they are stored in implementation defined memory regions, typically the Data segment and the BSS.
If I popped the top of stack, which parameter will be popped first, num or ptr
The order of evaluation of arguments to a function is Unspecified.
So it depends on your compiler implementation. An compiler might evaluate the arguments from:
Left to Right or
Right to Left or
Any other random order
So the behavior & order you see would depend on this.
Adding to what #Als has already mentioned, most of the compilers on x86 follow _cdecl calling convention where arguments are evaluated from right to left. Learn more here
http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions#Standard_C_Calling_Conventions
#include<stdio.h>
int add(int,int);
int main()
{
int a;
a=add(5,7);
printf("%d",a);
}
int add(int x,int y)
{
x=x+y;
return(x);
}
Last night I got a doubt on return statement. See x is an auto variable defined inside the add function and as ANSI said an auto variable exists and has its lifetime only inside the function but here the return statement can make the variable a to exist even outside the function. Where does it store the value ? Stack or heap ?
Neither on the stack nor on the heap.
At least in the x86 architecture, the return value of functions is usually copied to the eax register, so it persists outside of the function. This is one of the reasons why you can't return an array but merely a pointer to it.
You can, however, return structs and other larger variables by value, in which case the compiler does some tricks by using the stack and additional registers such as edx.
What return actually does depends on the machine architecture to which the code is compiled. On a machine with registers the value of x is copied to a register. The caller will pick up the value from there and do something with it. Here, that value is copied to a variable named a.
If this code is compiled on a stack machine, the return value might be just left on the stack itself. The object code for calling the add function will look something like this:
push 7
push 5
call add
seti 0x28ccf4
add will pop the values from the stack, add them together and push the result back to the stack. (If the function deals with data structures that will not find into a slot on the stack, their addresses are pushed instead.) seti is an operation that will pop a value from the stack and assign it to the integer variable at a particular address. (Here, 0x28ccf4 is the address of a.). As the top of the stack will now contain the result of adding 5 and 7, the value of a will become 12.
It varies. In a typical case, you can count on anything up to at least the size of an int being returned in some register(s) (e.g., typically eax on x86, $v0-$v1 on MIPS, r0 on ARM).
On many machines, larger return values (e.g., a struct with several members) will result in the caller allocating space on the stack to hold the return value, and either passing a pointer to that space as a hidden argument to the function, or the function having implicit knowledge of the location of that space relative to (for example) the stack pointer when the function was entered.
Though the question is tagged C, I'll also mention that in C++ there are a few special rules about return values. Specifically, there's a return value optimization and a named return value optimization. These allow a compiler to elide code for copying a return value, even if/when (for example) the copy would normally have visible side effects. These are intended to allow optimization where the function constructs a return value where the calling code will need it, rather than constructing it locally in the function, and then making a copy back to where the calling code can use it.
It is stored in a register in most platforms I know about, but this could be changed by compiler implementation.
It is worth noticing that while return x where x is a value and not pointer, such as in you case is legitimate, if x is a pointer, you should make sure that the buffer / data it points to is valid when the function returns, otherwise it will be a valid pointer that points to invalid location.
This is most likely covered in programming language course if you are a CS student. Anyway, you can check out the Wikipedia.
And in fact, it is stored in the call stack, aka stack.
The return value of add function is copied back to 'a' in the main function. The auto variables declared within a function are present in the activation record for that function on the call stack and the activation record is removed at the end of function execution, after copying any return value back to the caller's variable..