Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: x86 Stack Confusion

Reply
Thread Tools

Re: x86 Stack Confusion

 
 
Chuck F.
Guest
Posts: n/a
 
      01-10-2006
Eric Sosman wrote:
>

.... snip ...
>
> What we lost in the exchange (TANSTAAFL) was the ability to
> substitute user-defined replacements for the Standard library
> functions: if you've got a more accurate inverse cosine, you
> can't call it acos(). The place this becomes most irksome is
> with malloc() and friends, where debugging could be enormously
> improved if only we could insert our own instrumented versions.
> Alas, the Standard forbids it on pain of undefined behavior.


Actually you often can do just that (substitution). However it
isn't portable.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
Reply With Quote
 
 
 
 
Chuck F.
Guest
Posts: n/a
 
      01-10-2006
Keith Thompson wrote:
> "Chuck F. " <(E-Mail Removed)> writes:
>> Grumble wrote:

>
>>> As far as I understand, C89 and C99 leave the details of
>>> parameter passing up to the implementation. For that reason,
>>> I've claimed in comp.lang.asm.x86 that there is no such
>>> thing as "the C calling convention". Am I mistaken? ]

>>
>> No. However, C is almost unique among languages in having the
>> error prone variadic functions available, which in turn
>> mandate having the first parameter in a known place, and makes
>> the reverse order (assuming a stack, which is not necessary)
>> attractive.

>
> Not just the first parameter; there can be one or more
> parameters before the "...".


When I wrote that I thought about being that explicit, and decided
that it wasn't worthwhile, since it doesn't affect the point.
Besides, nobody would bother correcting and expanding it

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      01-10-2006
"Dik T. Winter" <(E-Mail Removed)> wrote:

> In article <(E-Mail Removed)> Keith Thompson <(E-Mail Removed)> writes:
> > http://www.velocityreviews.com/forums/(E-Mail Removed) (Dag-Erling Smørgrav) writes:
> > > "osmium" <(E-Mail Removed)> writes:
> > >> When a knowledgeable person says "C calling convention", *this* is
> > >> what he means. There is nothing analogous to printf() with it's
> > >> indeterminate number of parameters in, Pascal, for example.
> > >
> > > Yes, there is. Write() and WriteLn() both take a variable number of
> > > arguments. There is however no way for the programmer to define a
> > > procedure which takes a variable number of arguments.

> >
> > Yes, but as I recall the Write and WriteLn procedures, unlike C's
> > printf(), are "magical".

>
> Yes, they are. In the same way as variadic functions are magical.


No, they aren't. Variadic functions are available to the user-
programmer. The mechanism that powers Write and WriteLn is only
available to the implementor.

Richard
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      01-10-2006
John Devereux a écrit :
> "Robert Gamble" <(E-Mail Removed)> writes:
>
>
>>John Devereux wrote:
>>
>>>Keith Thompson <(E-Mail Removed)> writes:
>>>
>>>
>>>>(E-Mail Removed) (Dag-Erling Smørgrav) writes:
>>>>
>>>>>"osmium" <(E-Mail Removed)> writes:
>>>>>
>>>>>>When a knowledgeable person says "C calling convention", *this* is
>>>>>>what he means. There is nothing analogous to printf() with it's
>>>>>>indeterminate number of parameters in, Pascal, for example.
>>>>>
>>>>>Yes, there is. Write() and WriteLn() both take a variable number of
>>>>>arguments. There is however no way for the programmer to define a
>>>>>procedure which takes a variable number of arguments.
>>>>
>>>>Yes, but as I recall the Write and WriteLn procedures, unlike C's
>>>>printf(), are "magical". There's no format string, so it's up to the
>>>>compiler to generate code based on the actual argument types. A
>>>>compiler might typically generate a distinct procedure call for each
>>>>argument. It's more like special-case overloading than C's "..."
>>>>mechanism. Since the compiler can do whatever it likes, there's no
>>>>need for special-purpose calling conventions to make everything come
>>>>out right.
>>>>
>>>>This is perhaps marginally off-topic, but it does illustrate some of
>>>>the design decisions that went into C. C implements its I/O functions
>>>>using (more or less) ordinary function calls, while Pascal uses
>>>>compiler magic.
>>>
>>>Actually gcc for example will typically silently replace
>>>
>>> printf("Hello\n");
>>>
>>>with
>>>
>>> puts("Hello\n");

>>
>>ITYM:
>>puts("Hello");

>
>
>
> Yes, you are correct! - I admit I never knew that puts() appends a
> newline... In fact the only reason I ever encountered it in the first
> place is tracking down why printf was not being linked in!
>
> #include <stdio.h>
>
> int main(void)
> {
> printf("Hello, World!\n");
> }
>
>
> <sorry for OT-ness>:
>
> .file "test.c"
> .section .rodata
> .LC0:
> .string "Hello, World!"
> .text
> .globl main
> .type main, @function
> main:
> pushl %ebp
> movl %esp, %ebp
> subl $8, %esp
> andl $-16, %esp
> movl $0, %eax
> addl $15, %eax
> addl $15, %eax
> shrl $4, %eax
> sall $4, %eax
> subl %eax, %esp
> subl $12, %esp
> pushl $.LC0
> call puts
> addl $16, %esp
> leave
> ret
> .size main, .-main
> .ident "GCC: (GNU) 4.0.3 20051201 (prerelease) (Debian 4.0.2-5)"
> .section .note.GNU-stack,"",@progbits
>
>

Why this "optimization"?

To cheat in benchmarks that report the size of a "hello world"
program.

Note that if I replace the gcc libc with another library
where puts returns either 1 or zero (conforming implementation)
I will get the wrong results.
 
Reply With Quote
 
John Devereux
Guest
Posts: n/a
 
      01-10-2006
jacob navia <(E-Mail Removed)> writes:

> Why this "optimization"?
>
> To cheat in benchmarks that report the size of a "hello world"
> program.


I don't think so. I think it is part of a general optimization of many
"built-in" functions (like e.g. memcpy, malloc etc). Because they are
standard functions, the compiler is able to implement calls to them as
modified calls to other functions, or inline sequences.

> Note that if I replace the gcc libc with another library
> where puts returns either 1 or zero (conforming implementation)
> I will get the wrong results.


No, if I actually *use* the return value of printf, then it does call
printf:

#include <stdio.h>

int main(void)
{
volatile int a = printf("Hello, World!\n");
}

.file "test.c"
.section .rodata
..LC0:
.string "Hello, World!\n"
.text
..globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
subl $12, %esp
pushl $.LC0
call printf
addl $16, %esp
movl %eax, -4(%ebp)
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.0.3 20051201 (prerelease) (Debian 4.0.2-5)"
.section .note.GNU-stack,"",@progbits


--

John Devereux
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-10-2006
"Dik T. Winter" <(E-Mail Removed)> writes:
> In article <(E-Mail Removed)> Keith Thompson
> <(E-Mail Removed)> writes:
> > (E-Mail Removed) (Dag-Erling Smørgrav) writes:
> > > "osmium" <(E-Mail Removed)> writes:
> > >> When a knowledgeable person says "C calling convention", *this* is
> > >> what he means. There is nothing analogous to printf() with it's
> > >> indeterminate number of parameters in, Pascal, for example.
> > >
> > > Yes, there is. Write() and WriteLn() both take a variable number of
> > > arguments. There is however no way for the programmer to define a
> > > procedure which takes a variable number of arguments.

> >
> > Yes, but as I recall the Write and WriteLn procedures, unlike C's
> > printf(), are "magical".

>
> Yes, they are. In the same way as variadic functions are magical.


No, not quite. In C, variadic functions are a feature of the
language, and users are free to write their own. Because of this, the
compiler has to handle them in the general case (though it can
optimize particular instances). Pascal's Write and Writeln, on the
other hand, are unique in the language. They're effectively special
operators handled by the compiler rather than true functions.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-10-2006
jacob navia <(E-Mail Removed)> writes:
> John Devereux a écrit :

[...]
>> Yes, you are correct! - I admit I never knew that puts() appends a
>> newline... In fact the only reason I ever encountered it in the first
>> place is tracking down why printf was not being linked in!
>> #include <stdio.h>
>> int main(void)
>> {
>> printf("Hello, World!\n");
>> }
>> <sorry for OT-ness>:
>> .file "test.c"
>> .section .rodata
>> .LC0:
>> .string "Hello, World!"
>> .text

[snip]
>> call puts

[snip]
>>

> Why this "optimization"?
>
> To cheat in benchmarks that report the size of a "hello world"
> program.


In what sense is it cheating? By calling puts() rather than printf(),
it saves the overhead of parsing the format string.

> Note that if I replace the gcc libc with another library
> where puts returns either 1 or zero (conforming implementation)
> I will get the wrong results.


The program doesn't use the result of printf(). The optimization is
perfectly valid.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Grumble
Guest
Posts: n/a
 
      01-10-2006
Eric Sosman wrote:
> The interesting point here is that prior to ANSI C, few
> if any compilers could perform such optimizations. ANSI made
> the Standard library function names off-limits for other uses,
> and suddenly it became possible for the compiler to "know" that
> printf() wasn't just J. Random Function but a function about
> which it coult have built-in knowledge. Similar knowledge makes
> it possible to compile sqrt() and memcpy() and various other
> Standard library functions in-line.
>
> What we lost in the exchange (TANSTAAFL) was the ability to
> substitute user-defined replacements for the Standard library
> functions: if you've got a more accurate inverse cosine, you
> can't call it acos(). The place this becomes most irksome is
> with malloc() and friends, where debugging could be enormously
> improved if only we could insert our own instrumented versions.
> Alas, the Standard forbids it on pain of undefined behavior.


If I have the source code, can't I just implement mymalloc() and
then #define malloc mymalloc

I suppose I can't do it if I don't have the source...
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      01-10-2006
In article <43c3bb9e$0$31595$(E-Mail Removed)>,
Grumble <(E-Mail Removed)> wrote:
>If I have the source code, can't I just implement mymalloc() and
>then #define malloc mymalloc


Aside from whether it's legal to use the reserved identifier "malloc"
in that way, note that you will only be changing your own direct uses
of malloc, not those of other standard library functions (e.g. printf
may well call malloc).

-- Richard
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      01-10-2006
On 2006-01-10, Richard Tobin <(E-Mail Removed)> wrote:
> In article <43c3bb9e$0$31595$(E-Mail Removed)>,
> Grumble <(E-Mail Removed)> wrote:
>>If I have the source code, can't I just implement mymalloc() and
>>then #define malloc mymalloc

>
> Aside from whether it's legal to use the reserved identifier "malloc"
> in that way,


It is.

> note that you will only be changing your own direct uses of malloc,
> not those of other standard library functions (e.g. printf may well
> call malloc).


for the record - standard library functions which use malloc (directly
or indirectly) on my implementation:

fopen, fseek (may defer allocating a buffer until fseek is called), any
function that does wide character output (calls a helper function that,
among other things, may allocate a buffer), setbuf/setvbuf (obviously),
vfprintf (called by other ...printf funcs) to build a table of its
argument types, setenv, atexit - and, obviously, calloc.

Note that you're not expected to free() any of the resulting objects
yourself. However, there is a common extension strdup() where you are,
and another (maybe somewhat less common) one asprintf() which also takes
a pointer to a malloc'ed object which it expects to be able to
realloc().

> -- Richard

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C/C++ compilers have one stack for local variables and return addresses and then another stack for array allocations on the stack. Casey Hawthorne C Programming 3 11-01-2009 08:23 PM
x64 vs x86.. surprising results in performance (x86 better)? markm75 Windows 64bit 7 01-09-2008 06:41 PM
Why is there an x86 emu if a processor is x86-64? =?Utf-8?B?RWxsaW90IEh1ZGdpbnM=?= Windows 64bit 4 07-23-2006 11:52 PM
x86 Mac Laptop and x86 iMac now available Daniel NZ Computing 11 01-17-2006 12:11 PM
Is there a way with Linux x86 to report a way the current stack trace for a thread? kevin.hall@motioneng.com C++ 4 10-20-2005 09:43 PM



Advertisments