printf (' hello world! ');

Kevin Buettner kev@primenet.com
Fri, 30 Jun 2000 17:37:24 -0700


On Jun 30,  5:12pm, Shawn T. Rutledge wrote:

> > > You can do assembly in Linux, the assembler is as86.  There is also
> > > nasm I believe.  
> > 
> > Don't forget gas.  (The GNU ASsembler used by gcc.)
> 
> The man page for as says that it is the GNU assembler.  I thought
> maybe as86 was the x86 component of it but they are actually two
> separate executables on my system.

The man page for as86 (on my system) says that it takes source
files whose syntax is closer to that of the intel/microsoft assembler.
It's not clear to me if it's built on top of gas or not.

> > > But I haven't done it.  I suspect you could still
> > > make function calls to libc functions for doing output, etc.  I
> > > don't think it gets much use outside the kernel itself.
> > 
> > I think you're talking about inline assembler.  It comes in handy from
> 
> No I was talking about how to do hello world...

I see.

> ...you'd need to write to stdout.  That would involve either a libc
> call or a direct ioctl call wouldn't it?

Right.  The example that I gave called libc's write().  But the
implementation of write() in libc just consists of setting up some
registers and then doing a syscall.  It's kind of interesting to
look at, so here it is:

(gdb) x/24i write
0x4000ef00 <__libc_write>:      push   %ebx
0x4000ef01 <__libc_write+1>:    mov    0x10(%esp,1),%edx
0x4000ef05 <__libc_write+5>:    mov    0xc(%esp,1),%ecx
0x4000ef09 <__libc_write+9>:    mov    0x8(%esp,1),%ebx
0x4000ef0d <__libc_write+13>:   mov    $0x4,%eax
0x4000ef12 <__libc_write+18>:   int    $0x80
0x4000ef14 <__libc_write+20>:   pop    %ebx
0x4000ef15 <__libc_write+21>:   cmp    $0xfffff001,%eax
0x4000ef1a <__libc_write+26>:   jae    0x4000ef1d <__libc_write+29>
0x4000ef1c <__libc_write+28>:   ret    
0x4000ef1d <__libc_write+29>:   push   %ebx
0x4000ef1e <__libc_write+30>:   call   0x4000ef23 <__libc_write+35>
0x4000ef23 <__libc_write+35>:   pop    %ebx
0x4000ef24 <__libc_write+36>:   xor    %edx,%edx
0x4000ef26 <__libc_write+38>:   add    $0x4945,%ebx
0x4000ef2c <__libc_write+44>:   sub    %eax,%edx
0x4000ef2e <__libc_write+46>:   push   %edx
0x4000ef2f <__libc_write+47>:   call   0x4000df80 <__errno_location>
0x4000ef34 <__libc_write+52>:   pop    %ecx
0x4000ef35 <__libc_write+53>:   pop    %ebx
0x4000ef36 <__libc_write+54>:   mov    %ecx,(%eax)
0x4000ef38 <__libc_write+56>:   or     $0xffffffff,%eax
0x4000ef3b <__libc_write+59>:   jmp    0x4000ef1c <__libc_write+28>

Notice that over half of the code is for dealing with errno.

Anyway, if you didn't want to drag libc into your executable, you
could do the ``int $0x80'' yourself.

Kevin