Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Jul 1998 17:55:06 -0700 (PDT)
From:      Steven Kehlet <kehlet@dt.wdc.com>
To:        Jonny <jvz@ns.nternet.net>
Cc:        hackers@FreeBSD.ORG
Subject:   Re:  Assembly..
Message-ID:  <Pine.GSO.3.96.980713171508.18643G-100000@hydra-X4>
In-Reply-To: <Pine.BSF.3.96.980713191737.12005A-100000@ns.nternet.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Hey, after searching through the source for as I think there must
be a bug or something.  The as that comes with FreeBSD is "a
pre-alpha version of the GNU assembler, version 1.92.3".  The latest
is 2.8.1.  Sounds suspect.  It looks like it should accept two args
to lcall if the first is an immediate 16 bit value and the second
an "absolute" value (preceeded by a '*'--this is new to me).  But
even trying to give the second value as an absolute, i.e. "lcall
$0x7,*0x0", it still won't compile.  I'll try downloading binutils
and compiling the newest gas for FreeBSD sometime...

I did however find a way around this... just use .byte and generate
the machine language yourself:

.byte   0x9a                    # opcode for lcall
.long   0x0                     # this will yield "lcall 0x7,0x0"
.word   0x7                     #

A gdb disassemble will show:

(gdb) disass main
Dump of assembler code for function main:
0x15b0 <main>:  pushl  $0x0
0x15b2 <main+2>:        leal   0x1,%eax
0x15b8 <main+8>:        pushl  0x1234
0x15be <main+14>:       lcall  0x7,0x0
End of assembler dump.
(gdb) 

... just like it should.  Oh yeah, though, there's one more weird thing.
Note that "pushl 0x1234" I stuck in there.  I found you need to
push this garbage value onto the stack before doing the lcall.  It
looks like the normal flow (which everyone keeps saying to do) is
to call _exit, which then lcalls the system call.  So there's a
return value there on the stack from the call to _exit, which the
kernel must skip when looking for the exit value you provide.  If
you don't do this, you'll get garbage for an exit value.  Go figure.

So here's the final product:

.text
.globl _main
_main:
        pushl   $0x0			# exit value
        leal    0x1,%eax		# 1 is system call code for exit
 
        pushl   0x1234                  # push a junk word onto stack
                                        # because syscall expects value
 
        .byte   0x9a                    # opcode for lcall
        .long   0x0                     # this will yield "lcall 0x7,0x0"
        .word   0x7                     #
 
END:                                    # so gdb stops disassembly here


Woohoo!  Nothing like spending a day figuring this out on company
time ;-).

Steve


On Mon, 13 Jul 1998, Jonny wrote:

> Date: Mon, 13 Jul 1998 19:20:52 -0400 (EDT)
> From: Jonny <jvz@ns.nternet.net>
> To: Steven Kehlet <kehlet@dt.wdc.com>
> Subject: Re:  Assembly..
> 
> sure man, i have been at this for a couple of weeks now
> and have gotten little or no information, everyone is like
> just use call syscallName, which is fine but i want to know
> how it works through and through, gcc -S shows it as
> lcall 0x7,0x0 why will it now assemble when you write
> the src yourself. also your correct in the different
> in linux and freebsd.. the pushing onto the stack in fbsd
> those i get np. thank you though for your input.. i will
> be sure to email you anything i get on the matter.
> 
> On Mon, 13 Jul 1998, Steven Kehlet wrote:
> 
> > Same here.  I've been trying to get this to work myself for about a
> > week.  Even the gcc info pages confirm the form "lcall 0x7,0x0", which
> > doesn't compile:
> > 
> >    * Immediate form long jumps and calls are `lcall/ljmp $SECTION,
> >      $OFFSET' in AT&T syntax; the Intel syntax is `call/jmp far
> >      SECTION:OFFSET'.  Also, the far return instruction is `lret
> >      $STACK-ADJUST' in AT&T syntax; Intel syntax is `ret far
> >      STACK-ADJUST'.
> >  
> > 
> > ???  If someone mails you the answer, mind forwarding it to me?
> > Thanks... also one thing.. FreeBSD pushes its arguments to the system
> > calls on the stack, as opposed to Linux which puts them in registers.
> > The system call code is put in %eax.
> > 
> > So the asm for exit is (I think ;-)):
> > 
> > pushl	$0		# exit status
> > leal    0x1,%eax	# 0x1 is call code for exit
> > lcall   0x7,0x0
> > 
> > 
> > Steve
> > 
> > 
> > 
> > On Sat, 11 Jul 1998, Jonny wrote:
> > 
> > > Date: Sat, 11 Jul 1998 15:08:34 -0400 (EDT)
> > > From: Jonny <jvz@ns.nternet.net>
> > > To: Luoqi Chen <luoqi@watermarkgroup.com>
> > > Cc: hackers@freebsd.org
> > > Subject: Re:  Assembly..
> > > 
> > > > > call 0x7,0x0
> > > > 
> > > > It should be a `far' call: lcall 0x7,0x0.
> > > > 
> > > > -lq
> > > 
> > > right, my bust. even so i continue to get operands dont match any known
> > > 386 instruction.
> > > 
> > > -> going out of my head =)
> > > 
> > > 
> > > To Unsubscribe: send mail to majordomo@FreeBSD.org
> > > with "unsubscribe freebsd-hackers" in the body of the message
> > > 
> > 
> 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.3.96.980713171508.18643G-100000>