环境: Centos(6.5 64位) gcc 4.4.7 20120313 内核 2.6.32-431.el6.x86_64
对于mmap的系统调用参数传递,参数传递对应的寄存器如下:
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
addr: %rdi
length: %rsi
prot: %edx
flags: %r10d
fd: %r8d
offset: %r9
在实现自己的mmap的时候除了flags参数对应的寄存器应用层和sys_mmap不一样外,其余的都是对应的,
所以在下面的代码中我们只用嵌入式汇编来修改flags对应的寄存器,即把flags值放入%r10d中
然后传入$9即__NR_mmap系统调用号到%eax中,然后在用系统调用命令syscall来进行系统调用,返回值在
%rax中,代码如下
#include <stdio.h>
#include <stdlib.h>
#include <asm/unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void *mymmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset)
{
unsigned long ret=0;
__asm__ __volatile
(
"mov $9, %%eax\n" //__NR_mmap系统调用号为9
"mov %1, %%r10d\n" //此处的r10d存放flags参数
"syscall\n"
"mov %%rax,%0\n"
:"=m"((long)ret)
:"m"(flags)
);
return (void*)ret;
}
int main(int argc,char *argv[])
{
char *p = NULL;
p = mymmap(NULL,256, PROT_WRITE | PROT_READ, MAP_PRIVATE |MAP_ANONYMOUS,-1,0);
memset(p,0,256);
p[0]=101;
printf("************************%p--%d\n",p[0]);//测试是否能正常使用
munmap(p,256);
return 0;
}