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 ... )