Frank, thanks for clarification of the calling convention between common function and system call. /adam

Frank Hofmann wrote:
On Wed, 11 Apr 2007, Adam Zhang wrote:

Hi Oliver,

Yes. the code was running on Linux. Thank you very much for the correction. You are right. i just check the AMD64 ABI (http://www.x86-64.org/documentation.html) that Solaris conforms to. Because the parameter I need transfer is char array, it needs to be put in the stack during the calling.

write(2) takes a pointer to that. Where you store the actual array is up to you.

But do you know where i can find the x86 ABI that Solaris uses?

You might've noticed that neither the AMD64 ABI nor the i386 ABI anywhere mention the system call mechanism (apart from the _exit special case in the i386 ABI, where it says you can 'lcall 7, $0'). It is deliberately undocumented, so that operating systems are free to choose the fastest method to perform a system call, and/or change that method, at any time.

If you want to know how a specific UNIX-style OS performs system calls, you can't look at the ABI document - but you'll have to look at the sourcecode for the OS' syscall handler and/or the actual binary of libc.

The calling conventions (it says "function calling sequence") for library interfaces that are described in the ABI are not the same as the system call mechanism. This is particularly obvious on Linux (where the 32bit userland ABI uses the 'normal' stack parameter passing while the system call mechanism passes args in regs), but also on Solaris (where you have multiple different ways of performing system calls).

FrankH.


Regards,
adam

Oliver Yang wrote:
Oliver Yang wrote:
Adam Zhang wrote:
Hi all,

i just write an independent write function in assembly language to write a string to stderr. But the code doesn't work on Solaris.
It seems you are using Gcc inline asm which will generate a system call by issuing "int 0x91".

But you should know, doesn't like Linux, on 32bit x86, Solaris passes parameters via stack by "push" instead of using registers.

That means, you should besides using %eax as syscall number, you should push necessary parameters into stack before issuing "int 0x91".
Hi Adam,

Sorry for my poor English. :-[

I have checked your code, I think you inline ASM code are learned from Linux, not Solaris. In your code, you are trying to pass parameters by registers before issuing int 0x91:

%eax: 0x4 -> syscall number %ebx: 0x2  --> fd
%ecx  buf address
%edx: int size

But actually, on Solaris x86 32bit kernel, except syscall number should be passed by %eax, other parameters should be passed by pushing them in stack, please refer to following code:

# /usr/sfw/bin/gcc test.c
# ./a.out
hello

# cat test.c
void write_stderr ( char * buf, int n )
{
int block[2];
block[0] = (int) buf;
block[1] = n;
__asm__ volatile (
"pushl %%ebx\n"
"movl  %0, %%ebx\n"
"pushl %%ebx\n"
"movl  $4, %%eax\n"
"push  4(%%ebx)\n"
"push  0(%%ebx)\n"
"push  $2\n"
"push  %%esp\n"
"int  $0x91\n"
"addl  $3,%%esp\n"
"movl  %%eax, 0(%%ebx)\n"
"popl  %%ebx\n"
: /*wr*/
: /*rd*/    "g" (block)
: /*trash*/ "eax", "edi", "ecx", "edx", "memory", "cc"
);
}


int main()
{
       char s[]="hello\n";
       write_stderr(s, sizeof(s) );
       return 0;
}

Another thing is, you should run your program on Solaris Nevada, because you used "int 0x91".


You could use mdb debug your program by setting break point before int 0x91, check whether you provide right parameters in stack and %eax.


Below is the code:

void write_stderr ( char * buf, int n )
{
  int block[2];
  block[0] = (int) buf;
  block[1] = n;
  __asm__ volatile (
"pushl %%ebx\n" "movl %0, %%ebx\n" "pushl %%ebx\n" "movl 0(%%ebx), %%ecx\n"
     "movl  4(%%ebx), %%edx\n"
"movl $4, %%eax\n" "movl $2, %%ebx\n" "int $0x91\n" "popl %%ebx\n" "movl %%eax, 0(%%ebx)\n"
     "popl  %%ebx\n"              : /*wr*/
     : /*rd*/    "g" (block)
     : /*trash*/ "eax", "edi", "ecx", "edx", "memory", "cc"
  );
}

Does anyone know where i am wrong?
Thank you!

Regards,
adam

_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code




_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code


_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to