.data
msg: .string "Hello, world.\n"
len = . - msg - 1
.text
global _start
_start:
movl $4, %eax
movl $1, %ebx
movl $msg, %ecx
movl $len, %edx
int $0x80
movl $1, %eax
xorl %ebx, %ebx
int $0x80
Can anyone explain what I've done wrong?
As a related question, can anyone point me to the source for the int
0x80 handler? I've looked all over but can't find it.
Thanks.
To Unsubscribe: send mail to majo...@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
> >From what I understand, the following should print "Hello, world." on
> stdout. I stole the code from the Linux HOWTO, but I think it should
> work on FreeBSD as well. Instead, the call to write returns 9 (EBADF).
>
[ Linux-specific asm elided ... ]
>
> Can anyone explain what I've done wrong?
>
> As a related question, can anyone point me to the source for the int
> 0x80 handler? I've looked all over but can't find it.
You're trying to run Linux assembly on FreeBSD. The calling conventions
are not the same at all, and cannot be treated as such. Even if you
really needed to write in assembly, you shouldn't call the syscalls
directly. Note that the library stubs are just that, stubs to call
the system calls. Try doing something more along the lines of:
pushl $stringlen
pushl stringaddr
pushl $0x1
call write
which would result in %eax containing the return value.
For what it's worth, you can find all of the syscall calling conventions
in src/lib/libc, and you can find where the calling conventions are
"defined" by looking at src/sys/i386/i386/trap.c.
> Thanks.
--
Brian Fundakowski Feldman \ FreeBSD: The Power to Serve! /
gr...@FreeBSD.org `------------------------------'
It turns out that placing the int $0x80 behind a call is required. I
infer that
the kernel does not look for the arguments at the top of the stack, but
farther
down. When you think about it, that makes some sense, since any sane
person would
call the kernel through libc, and not directly. Thanks for the help.
In the remote chance that anyone is interested, here is the code that
works:
.data
msg: .string "Hello, world.\n"
len = . - msg - 1
.text
.global _start
_start:
pushl $len
pushl $msg
pushl $1
movl $4, %eax
call make_syscall
addl $12, %esp
movl $1, %eax
pushl $0
call make_syscall
make_syscall:
int $0x80
ret
I couldn't find any documentation for FreeBSD, so used what I found for
Linux as a first approximation. At least it assembled and ran, even if
it didn't work.
> Even if you
> really needed to write in assembly, you shouldn't call the syscalls
> directly.
I'm doing this as a learning exercise, so I wanted to do it the hard way
first.
> Note that the library stubs are just that, stubs to call
> the system calls. Try doing something more along the lines of:
>
> pushl $stringlen
> pushl stringaddr
> pushl $0x1
> call write
>
> which would result in %eax containing the return value.
Using write, and making the other appropriate changes to the code,
works. write() uses
leal 4, %eax
instead of
movl $4, %eax
before the int $0x80 call. But doing this myself still does not work. At
first glance, it doesn't seem that the C startup stuff does anything
that would affect syscalls, so I don't see why calling write() would
make a difference.
> For what it's worth, you can find all of the syscall calling conventions
> in src/lib/libc, and you can find where the calling conventions are
> "defined" by looking at src/sys/i386/i386/trap.c.
It looks like syscall() in trap.c is where int $0x80 is handled. I'll
have to do some more digging. Thanks for the help.
I disassembled FreeBSD programs (create a small C prog, compile, and use
objdump), and it looks more like this: (I haven't tested this yet, but it is definitely
stack based, not register based, the part which I haven't tested is if the placing
the int $0x80 behind a call is required)
pusl $len
pushl $Msg
pushl $1
mov $4,%eax
call _basicsyscall
addl $12,%esp
.
.
.
_basicsyscall: int $0x80
ret
> As a related question, can anyone point me to the source for the int
> 0x80 handler? I've looked all over but can't find it.
On the libc side?
It is very fragmented in several files using a lot of macro
code. If you wish I can look up the names for you (I did this some weeks ago)
I never searched for the kernel side. (the actual 0x80 handler)
Marco van de Voort (Mar...@Stack.nl)
<http://www.stack.nl/~marcov/xtdlib.htm>