20

I am a beginner in C programming language, recently I have started learning functions, I have studied that functions use keyword return to return a value in the caller function. For example the following program.

int getVal(){
 return 1000;
}

int main(){
int x = getVal();
printf("x = %d",x);
return 0;
}

will print x = 1000

but I am confused that (under turbo C compiler 32 bit) why the following program is producing output as x = 1000 too. Please explain.

int get_val(){
 _AX = 1000;
}

int main(){
int x = get_val();
printf("x = %d",x);
return 0;
}
Mayank Tiwari
  • 2,974
  • 5
  • 30
  • 52

4 Answers4

26

The "return value" is returned in a particular register (defined by the "ABI", the Application Binary interface, which describes how compilers should generate their code), in most x86 systems, that is EAX (32 bit) or AX (16 bit) [not saying _AX isn't actually EAX internally].

This compiler obviously supports using a "register" directly by naming it _AX. So by loading the [E]AX register with a value, we are essentially returning this value.

This definitely won't work in any other compiler, although inline assembler can achieve the same thing.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
13

In C here, _AX is a pseudo register. And when you do AX=1000, this value 1000 is taken from the Accumulator

But it may not work as expected in GCC compiler

Compile and Run the following program in Turbo C, you will get 35 as output. It may not work in other compilers.

#include<stdio.h>  
int main()  
{
    int a = 0;  
    a = 35;  
    printf("%d");  
    return 0;
}  

Assume the address of a = 1200. Assume the address of video memory = 5500;

MOV AH, 35  
MOV [1200], AH  
MOV [5500], AH // prints on the screen.  

This is the way of execution takes place. After copying the value 35 to location 1200, AH retains the value 35.

Then printf("%d") tries to get the value from AH and sends to video memory to display it on screen.

If we use printf("%d %d", age, salary), the value of age transfered to AH before using that value to send to video memory. Then the value of salary is moved to AH then send to video memory.

Assume, Address of age = 1200; Address of salary= 1202; Address of video memory = XXXX; (It will changed according to no. of chars printed on the screen, dont think much about this address value)

MOV AH, [1200]
MOV [XXXX], AH
MOV AH, [1202]
MOV [XXXX], AH

I hope this will help to understand the solution for the given program.

  • 1
    Ahaa it reminds me college day programming, see accumulator uses because return value immediately assigned when control returns to calling function so gcc also use `a` register. But thing is this code(syntax-wise) not supported by gcc compiler. Writing assembly code in C is called inline-assembly, and its compiler dependent (in syntax also) – Grijesh Chauhan Jul 20 '13 at 19:53
  • 1
    @GrijeshChauhan: Sharing what you know is a Prime Factor Sir, Votes and rep are secondary! –  Jul 20 '13 at 19:56
  • Ah I forgot to share one more thing, try to disassemble executable compiled by gcc (using `objdump exename`) or get compiled assembly code (`gcc -S code.c`) and check register for return. – Grijesh Chauhan Jul 20 '13 at 20:00
6

According to TC compiler (32 bit), the returned value of a function is stored in Accumulator (AC), and it can be accessed in TC compiler using _AX, so when you write:

_AX = 1000;

means that you are placing value 1000 inside Accumulator, and when the function completes its execution and the control reaches to the caller function, then the value of Accumulator is checked, and in this case this value will be stored in x.

here the statement

x = get_val();

would be simply

x = 1000;

but this would be in your case only, means in (TC 32 bit windows compiler), it may or may not work for other compilers.

Mayank Tiwari
  • 2,974
  • 5
  • 30
  • 52
  • I wonder if Borland still allows this with C++ Builder? Back when it was first released, Macs were running on PPC CPUs, which have no AX, EAX, etc. registers... –  Jul 21 '13 at 09:18
0

in getval(), 1000 is stored in accumulator,and getval() will give compile time warning that function should return a value,then in the main, x will be assigned the value returned or stored in the accumulator which is 1000, that's why it will print x=1000.

akay
  • 91
  • 1
  • 10
  • Note that the accumulator is a CPU register and that you are getting the result 1000 by luck. – Paul Floyd Jul 10 '17 at 13:50
  • then why it is happening by luck even... can you plz tell, then many of us will come to know about it... – akay Jul 16 '17 at 16:54
  • On Linux 64bit Compiler Explorer shows this: https://godbolt.org/g/R8ggW9. You can see that for the correct return the value is stored in eax. The version without a return will pick up whatever value is in eax. This could be the last value used, or it could be some 'random' left over value. – Paul Floyd Jul 16 '17 at 19:42
  • thanks, buddy... it'll be really helpful for others as well – akay Jul 17 '17 at 10:20