The HyperNews Linux KHG Discussion Pages

## would be nice to explain syscall macros

  Forum: How System Calls Work on Linux/i86
  Keywords: sycall
  Date: Fri, 13 Sep 1996 01:37:11 GMT
  From: Tim Bird <tbird@caldera.com>

The syscall macros are a little dense to decipher. It took me a while to determine how the macro syscall1(int,setuid,uid_t,uid) expanded into the assembly code shown. It might be nice to show the macro, and explain a little about how it gets expanded. Here is the source for the _syscall1 macro
    	#define _syscall1(type,name,type1,arg1) \
    	type name(type1 arg1) \
    	{ \
    	long __res; \
    	__asm__ volatile ("int $0x80" \
            	: "=a" (__res) \
            	: "0" (__NR_##name),"b" ((long)(arg1))); \
    	if (__res >= 0) \
            	return (type) __res; \
    	errno = -__res; \
    	return -1; \
    	}
    When expanded, this become the code
    	int setuid(uid_t uid)
    	{
    		long __res;
    		__asm__ volatile ("int $0x80" \
    			: "=a" (__res) \
    			: "0" (__NR_setuid), "b" ((long)(uid)));
    		if (__res >= 0 )
    			return (int) __res;
    		errno = -__res;
    		return -1;
    	}
    It's pretty easy to see how the cleanup code converts
    into assembly, but the setup code eluded me until
    I figured out the following:
    	"=a" (__res) means the result comes back in %eax
    	"0" (__NR_setuid) means put the system call number
    		into %eax on entry
    	"b" ((long)(uid) means put the first argument
    		into %ebx on entry
syscallX macros that use additional parameters use %ecx, %edx, %esi, and %edi to hold additional values passed through the call.