Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Linux / NASM equivalent of Iczelion's Win32 assembly tut's

Reply
Thread Tools

Re: Linux / NASM equivalent of Iczelion's Win32 assembly tut's

 
 
Herbert Kleebauer
Guest
Posts: n/a
 
      03-05-2008
Frank Kotler wrote:


> I observed that you code "looks like" it calls the OS for every
> character. It does not.


Now GCC disappoints me. Just compiled the two line C program:

#include <stdio.h>
main() {putchar(10);}

GCC gives me:

main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $20, %esp
movl stdout, %eax
movl $10, (%esp)
movl %eax, 4(%esp)
call _IO_putc
addl $20, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)"
.section .note.GNU-stack,"",@progbits

This means, for each putchar() in the source, _IO_putc is called.


The Microsoft C compiler defines the macro putchar() in stdio.h

#define putchar(_c) putc((_c),stdout)
#define putc(_c,_stream) (--(_stream)->_cnt >= 0 \
? 0xff & (*(_stream)->_ptr++ = (char)(_c)) : _flsbuf((_c),(_stream)))

And therefore the compiled code looks like:

; 3 : main() {putchar(10);}

00000 a1 24 00 00 00 mov eax, DWORD PTR __iob+36
00005 48 dec eax
00006 a3 24 00 00 00 mov DWORD PTR __iob+36, eax
0000b 78 14 js SHORT $L201
0000d a1 20 00 00 00 mov eax, DWORD PTR __iob+32
00012 c6 00 0a mov BYTE PTR [eax], 10 ; 0000000aH
00015 a1 20 00 00 00 mov eax, DWORD PTR __iob+32
0001a 40 inc eax
0001b a3 20 00 00 00 mov DWORD PTR __iob+32, eax
00020 c3 ret 0
$L201:
00021 68 20 00 00 00 push OFFSET FLAT:__iob+32
00026 6a 0a push 10 ; 0000000aH
00028 e8 00 00 00 00 call __flsbuf
0002d 83 c4 08 add esp, 8
00030 c3 ret 0
_main ENDP

It only calls an external subroutine when the buffer is full.
 
Reply With Quote
 
 
 
 
Tim Prince
Guest
Posts: n/a
 
      03-05-2008
Herbert Kleebauer wrote:
> Frank Kotler wrote:
>
>
>> I observed that you code "looks like" it calls the OS for every
>> character. It does not.

>
> Now GCC disappoints me. Just compiled the two line C program:
>
> #include <stdio.h>
> main() {putchar(10);}
>
> GCC gives me:
>
> main:
> leal 4(%esp), %ecx
> andl $-16, %esp
> pushl -4(%ecx)
> pushl %ebp
> movl %esp, %ebp
> pushl %ecx
> subl $20, %esp
> movl stdout, %eax
> movl $10, (%esp)
> movl %eax, 4(%esp)
> call _IO_putc
> addl $20, %esp
> popl %ecx
> popl %ebp
> leal -4(%ecx), %esp
> ret
> .size main, .-main
> .ident "GCC: (GNU) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)"
> .section .note.GNU-stack,"",@progbits
>
> This means, for each putchar() in the source, _IO_putc is called.


You want gcc to over-ride the headers provided by Ubuntu (and make
similar provisions for each target), even if you don't invoke whatever
options are present in your particular header?
 
Reply With Quote
 
 
 
 
Richard Tobin
Guest
Posts: n/a
 
      03-05-2008
In article <>,
Herbert Kleebauer <> wrote:

>This means, for each putchar() in the source, _IO_putc is called.


I think this is for thread-safety (so multiple threads can use the
same stream simultaneously, though that seems like a Really Bad Idea).
There may be some way to override it.

-- Richard
--
:wq
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      03-06-2008
In article <>
Herbert Kleebauer <> wrote:
>Now GCC disappoints me. Just compiled the two line C program:
>
>#include <stdio.h>
>main() {putchar(10);}


[assembly snipped]

>This means, for each putchar() in the source, _IO_putc is called.


It is possible that any putchar() calls _IO_putc(), but the above
does not show this (even if you put back the assembly that I
snipped). The reason is that 10 happens to be equal to value of
'\n' on this system, and putchar('\n') must push the output to the
system if the stream in question is line-buffered. Since stdout
is very often line-buffered, one should expect putchar('\n') to
make an O/S call very often as well, and an implementation-specific
function like _IO_putc() is a good place to hide the test for
whether the call is needed, along with the call itself.

On the other hand, putchar('x'), for instance, could be done without
making a function call (since 'x' is clearly not a newline).
Similarly, a source-code construct like putchar(c), where c is a
variable rather than a known-constant newline, might expand to code
that tests whether c=='\n', then buffers c or calls _IO_putc(c) as
appropriate. (As someone suggested in another follow-up, one might
need to turn off thread support to see this, too.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      03-06-2008
In article <>,
Chris Torek <> wrote:

>It is possible that any putchar() calls _IO_putc(),


.... and it seems to be true on the Linux systems I have access to. It
appears to be for thread-safety, but making writes to the same file
"thread-safe" is not very useful: it guarantees that you won't, for
example, get a segmentation fault, but the characters may come out in
any order. To make the pointless case safe at the expensive of making
the common case slow seems like a mistake to me.

>Since stdout
>is very often line-buffered, one should expect putchar('\n') to
>make an O/S call very often as well, and an implementation-specific
>function like _IO_putc() is a good place to hide the test for
>whether the call is needed, along with the call itself.


That was my initial guess as to the explanation too, but it turns out
to be wrong.

-- Richard
--
:wq
 
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 to NASM - lnkflat problem Marcin Balcerzak C Programming 3 06-03-2005 02:22 AM
Assembly's manifest definition does not match the assembly reference. Horatiu Margavan via .NET 247 ASP .Net 0 08-30-2004 04:14 PM
ASP.NET 2.0: What is the namespace and assembly name of generated assembly SA ASP .Net 0 08-09-2004 05:09 PM
Referencing assembly from GAC using @assembly fails Brent ASP .Net 1 01-23-2004 08:23 PM
can a strongly named assembly reference a regular assembly? Prasanna Padmanabhan ASP .Net 1 11-19-2003 06:21 AM



Advertisments