系统调用
直接利用系统调用输出Hello生成elf文件
$ ll asm
-rwxr-xr-x 1 fifan root 1202 Jan 25 18:59 asm
只有1202字节,而用printf则会生成>10k的文件
源代码
asm.c
#include <asm/unistd.h>
int errno;
_syscall3(int, write, int, fd, char *, data, int, len);
_syscall1(int, exit, int, status);
_start()
{
write(0, "Hello/n", 6);
exit(0);
}
在/usr/include/asm/unistd.h中有关于系统调用的宏定义,与程序相关的有
#define __NR_exit 1
#define __NR_write 4
#define __syscall_return(type, res) /
do { /
if ((unsigned long)(res) >= (unsigned long)(-125)) { /
errno = -(res); /
res = -1; /
} /
return (type) (res); /
} while (0)
#define _syscall1(type,name,type1,arg1) /
type name(type1 arg1) /
{ /
long __res; /
__asm__ volatile ("int $0x80" /
: "=a" (__res) /
: "0" (__NR_##name),"b" ((long)(arg1))); /
__syscall_return(type,__res); /
}
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) /
type name(type1 arg1,type2 arg2,type3 arg3) /
{ /
long __res; /
__asm__ volatile ("int $0x80" /
: "=a" (__res) /
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), /
"d" ((long)(arg3))); /
__syscall_return(type,__res); /
}
内嵌汇编可参照blog中的《gcc编译c语言中内嵌汇编 》exit的系统调用号为1而write为4,系统调用号放在eax中,
linux系统调用最多可以有6个参数分别用ebx,ecx,edx,esi,edi,ebp(需要进行压栈保护),可以用gcc -E命令查看
宏替换后的代码,下面代码为方便更改了格式
$ cc -E asm.c
# 1 "asm.c"
# 1 "/usr/include/asm/unistd.h" 1 3
# 2 "asm.c" 2
int errno;
int write(int fd,char * data,int len)
{
long __res;
__asm__ volatile("int $0x80"
:
"=a" (__res)
:
"0" (4),"b" ((long)(fd)),"c" ((long)(data)), "d" ((long)(len)));
do
{
if ((unsigned long)(__res) >= (unsigned long)(-125))
{
errno = -(__res);
__res = -1;
}
return (int) (__res);
} while (0);
};
int exit(int status)
{
long __res;
__asm__ volatile ("int $0x80"
:
"=a" (__res)
:
"0" (1),"b" ((long)(status)));
do
{
if ((unsigned long)(__res) >= (unsigned long)(-125))
{
errno = -(__res);
__res = -1;
}
return (int) (__res);
} while (0);
};
_start()
{
write(0, "Hello/n", 6);
exit(0);
}
编译运行
[fifan@fifan fifan]$ cc -c asm.c
asm.c: In function `exit':
asm.c:6: warning: function declared `noreturn' has a `return' statement
[fifan@fifan fifan]$ ld -o asm asm.o
[fifan@fifan fifan]$ ./asm
Hello
[fifan@fifan fifan]$