GC

spc@gate.net spc@gate.net
Fri, 5 Apr 1996 19:07:03 -0500 (EST)


On some network somewhere in cyberspace, Eric W. Biederman transmitted:
> 
> [ a fun quible, means nothing ]
> >   It might be anachronistic of me, but I tend to want to look at the low
> > level code sometimes, as that may be the only way to solve a particularly
> > nasty problem (in porting joe to QNX, I ended up having to look at the
> > generated machine code to see that the frame pointer was being trashed
> > somehow and tracking it back to the problem).  Have you ever SEEN code
> > output from a compiler (say, like GCC)?  It's not readable by any standards. 
> > The Unix weenies tend to say "Well, assembly isn't for humans."  
> 
> Actually I've never had that problem, the assembly output from gcc is
> quite readable.  But ususally I don't have to type gcc -S to know what
> assembly has been generated either. 
> 
  Well, not to put a too find point on it, I ran the following C code
through 'gcc -S':

#include <stdio.h>
int main(void)
{
  printf("hello world\n");
  return(0);
}

  on two different systems, an AIX system, and Linux.  First, the oh so
beautiful output from the AIX version:

	.file	"hello.c"
.toc
.csect .text[PR]
gcc2_compiled.:
__gnu_compiled_c:
.csect _hello.rw_c[RO]
	.align 2
LC..0:
	.byte "hello world"
	.byte 10, 0
.toc
LC..1:
	.tc LC..0[TC],LC..0
.csect .text[PR]
	.align 2
	.globl main
	.globl .main
.csect main[DS]
main:
	.long .main, TOC[tc0], 0
.csect .text[PR]
.main:
	mflr 0
	st 31,-4(1)
	st 0,8(1)
	stu 1,-64(1)
	mr 31,1
	bl .__main
	cror 31,31,31
	l 3,LC..1(2)
	bl .printf
	cror 31,31,31
	lil 3,0
	b L..1
L..1:
	l 1,0(1)
	l 0,8(1)
	mtlr 0
	l 31,-4(1)
	br
LT..main:
	.long 0
	.byte 0,0,32,97,128,1,0,1
	.long LT..main-.main
	.short 4
	.byte "main"
	.byte 31
_section_.text:
.csect .data[RW]
	.long _section_.text

  Yea, real readable there.  Now, for the (slightly) better Linux version:

	.file	"hello.c"
	.version	"01.01"
gcc2_compiled.:
.section	.rodata
.LC0:
	.string	"hello world\n"
.text
	.align 16
.globl main
	.type	 main,@function
main:
	pushl %ebp
	movl %esp,%ebp
	pushl $.LC0
	call printf
	addl $4,%esp
	xorl %eax,%eax
	jmp .L1
	.align 16
.L1:
	movl %ebp,%esp
	popl %ebp
	ret
.Lfe1:
	.size	 main,.Lfe1-main
	.ident	"GCC: (GNU) 2.7.0"

  (And I'm not going to comment on that suflurious JMP there, hopefully that
would be optimized out).  Now, how I would do it (using a hypothetical
assembler):

;**********************************************************************
		section	text			; contains constant text strings

msg_hello	db	'hello world',10,0

;***********************************************************************
		section code			; contains code

						
main		push	ebp			;probably won't bother
		mov	ebp,esp			;with this as it's not
						;really needed
		push	msg_hello		;pushes address
		call	printf
		add	esp,4
		xor	eax,eax
		mov	esp,ebp
		pop	ebp
		ret

;***********************************************************************

		end	main

  Certainly a lot more readable than the mess GCC outputs, and certainly not
harder to output either.  And is it too hard to ask to maintain the
manufacturer's nmemonics?  Gee, I have all this 386 code, but it's in Intel
format, not the ghastly GCC/AT&T syntax.  

  And Eric, you probably don't work with Assembly that much to complain.  I
do, and I have my standards (I also have my C standards, and GNU/FSF doesn't
come close there either).

  -spc (And the worst assemblers I've used have been on Unix systems ... )