Why doesn't this function call save these registers?

S

Shi Jin

Hi there,

I am now having a puzzle regarding what a function call actually does when
called.
I have a simple code to see what's going on. It is simply calling another
simple function from main().
The disassembled code for the function under linux (with gcc) looks like this:

pushl %ebp ;push old %ebp
movl %esp, %ebp ;make new stack frame
subl $4, %esp ;make room for local variable---x
;then the code doing the calculation inside the function

But the corresponding instructions under WinXP(with MSVC7, same code ) is
push ebp
mov ebp,esp
sub esp,0CCh ; 0CCh=204
push ebx
push esi
push edi
.....

The problem is why doesn't linux push the registers ebx,esi,edi into the
stack to save them. Since the C calling convetion assumes that function
call do not modify ESI,EDI and EBX.

Is that because in the code under linux, those registers are not used. So
it is not necessary to back them up? Maybe in some other cases, they are
actually used, then there would be some push instructions, just like the
windows disassembled code. Is that true?

Another puzzle for me is that in the function, there is only one integer
as a local variable. So "subl $4, %esp" is enough for that. But I don't
know why the windows code uses "sub esp,0CCh", which sounds like 51 32-bit
variables are there. Or the number 51 is just some randomly large number?

Thanks for any comment or advice.

Shi
 
M

Matt Taylor

You are right that ebx, esi, edi, and ebp do not need to be saved if they
are not used. This is why GCC isn't saving them.
From the looks of things, I think you used VC in debug mode. In debug mode
the compiler adds extra data to the stack. For example, the buffer overrun
check and variable initialization checks add data to the stack. When
optimizations are enabled, smaller functions won't use a frame pointer, so
they don't initialize ebp.

-Matt
 
G

Gordon Burditt

I am now having a puzzle regarding what a function call actually does when
called.
I have a simple code to see what's going on. It is simply calling another
simple function from main().
The disassembled code for the function under linux (with gcc) looks like this:

pushl %ebp ;push old %ebp
movl %esp, %ebp ;make new stack frame
subl $4, %esp ;make room for local variable---x
;then the code doing the calculation inside the function

But the corresponding instructions under WinXP(with MSVC7, same code ) is
push ebp
mov ebp,esp
sub esp,0CCh ; 0CCh=204
push ebx
push esi
push edi
....

Nobody said the linkage conventions are the same for MSVC7 and gcc.
Nobody said you can link MSVC7 output and gcc output together and
get something that works (although if gcc uses MSVC7 libraries,
it is likely that you can.
The problem is why doesn't linux push the registers ebx,esi,edi into the
stack to save them. Since the C calling convetion assumes that function
call do not modify ESI,EDI and EBX.

*WHICH* C calling convention? Every compiler is free to have a different
one. It may even be true that code compiled with -O3.14159 cannot
be linked with code compiled with -O3.141592, as the linkage conventions
can be different.
Is that because in the code under linux, those registers are not used. So
it is not necessary to back them up?

Linkage conventions aren't going to require pushing and popping
registers unnecessarily. If the values are the same at exit as
at entry without pushing and popping, why bother doing it?
Maybe in some other cases, they are
actually used, then there would be some push instructions, just like the
windows disassembled code. Is that true?

Try writing some code that might use these and see. ESI and EDI might
be used in code that does array indexing with variables. Maybe.
Another puzzle for me is that in the function, there is only one integer
as a local variable. So "subl $4, %esp" is enough for that. But I don't
know why the windows code uses "sub esp,0CCh", which sounds like 51 32-bit
variables are there. Or the number 51 is just some randomly large number?

It may be room for the Microsoft DRM extensions at the register level.
Or perhaps it's room for Bill's wallet. Or maybe it has something to
do with C++ exceptions.

Gordon L. Burditt
 
B

Bryan Bullard

generally, stdcall or pascal (deprecated on windows) calling conventions are
used in the windows codebase. cases of cdecl (linux & unix) calling
convention is more rare in windows. the differences in these calling
conventions are well documented.

-bryan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top