dar*_*.pp 6 linux assembly reference nasm
我需要一些参考但是一个很好的参考,可能有一些很好的例子.我需要它因为我开始使用NASM汇编程序在汇编中编写代码.我有这个参考:
http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls.html
这是非常好的和有用的,但它有很多限制,因为它不解释其他寄存器中的字段.例如,如果我使用写入系统调用,我知道我应该在EAX寄存器中放置1,并且ECX可能是指向字符串的指针,但是EBX和EDX呢?我想要解释一下,EBX确定输入(stdin为0,其他为1等),EDX是要输入的字符串的长度等等.我希望你理解我想要的东西,我找不到任何这样的材料,所以这就是我在这里写的原因.提前致谢.
Ces*_*arB 10
Linux中的标准编程语言是C.因此,系统调用的最佳描述将它们显示为要调用的C函数.鉴于它们作为C函数的描述以及如何将它们映射到汇编中的实际系统调用的知识,您将能够轻松地使用任何您想要的系统调用.
首先,您需要一个对C程序员看来的所有系统调用的引用.我所知道的最好的是Linux man-pages项目,特别是系统调用部分.
我们以write系统调用为例,因为它是您问题中的一个.如您所见,第一个参数是有符号整数,通常是open系统调用返回的文件描述符.这些文件描述符也可以从父进程继承,通常发生在前三个文件描述符中(0 = stdin,1 = stdout,2 = stderr).第二个参数是指向缓冲区的指针,第三个参数是缓冲区的大小(作为无符号整数).最后,该函数返回一个有符号整数,即写入的字节数,或错误的负数.
现在,如何将其映射到实际的系统调用?有许多方法可以在32位x86上进行系统调用(根据您的寄存器名称,这可能是您正在使用的); 请注意,它在64位x86上完全不同(确保您在32位模式下组装并链接32位可执行文件;请参阅此问题以获取其他方法可能出错的示例).32位x86中最古老,最简单,最慢的int $0x80方法就是这种方法.
对于int $0x80方法,你把系统调用号%eax和参数%ebx,%ecx,%edx,%esi,%edi,并%ebp按此顺序.然后调用int $0x80,系统调用的返回值为on %eax.请注意,此返回值与引用所示的不同 ; 该参考显示了C库将如何返回它,但系统调用会返回-errno错误(例如-EINVAL).在这种情况下,C库会将此移动errno并返回-1.有关更多详细信息,请参阅syscalls(2)和intro(2).
因此,在该write示例中,您将write系统调用号放入%eax,第一个参数(文件描述符号)%ebx,第二个参数(指向字符串的指针)%ecx和第三个参数(字符串的长度)%edx.系统调用将以%eax写入的字节数或否定的错误号返回(如果返回值介于-1和-4095之间,则为否定的错误编号).
最后,您如何找到系统呼叫号码?他们可以在/usr/include/linux/unistd.h.在我的系统上,这只是包括/usr/include/asm/unistd.h,最后包括/usr/include/asm/unistd_32.h,所以数字在那里(因为write,你可以看到__NR_write是4).错误数字也是如此,它来自/usr/include/linux/errno.h(在我的系统上,在追逐包含链之后,我找到了第一个,/usr/include/asm-generic/errno-base.h其余的在/usr/include/asm-generic/errno.h).对于使用其他常量或结构的系统调用,它们的文档告诉您应该查看哪些标题以查找相应的定义.
现在,正如我所说,这int $0x80是最古老,最慢的方法.较新的处理器具有更快的特殊系统调用指令.为了使用它们,内核提供了一个虚拟动态共享对象(vDSO它就像一个共享库,但只在内存中),并且可以调用一个函数来使用可用于硬件的最佳方法进行系统调用.它还提供特殊功能来获取当前时间,甚至无需进行系统调用,以及其他一些事情.当然,如果您不使用动态链接器,则使用起来会有点困难.
还有另一种较旧的方法,vsyscall它类似于vDSO但在固定地址使用单个页面.不推荐使用此方法,如果您使用的是最新的内核,则会在系统日志中出现警告,可能会在更新的内核上启动时禁用,并且将来可能会被删除.不要使用它.
如果您下载该网页(如第二段中所示)并下载内核源代码,则可以单击“源”列中的链接,并直接转到实现系统调用的源文件。您可以阅读它们的 C 签名来了解每个参数的用途。
如果您只是寻找快速参考,那么每个系统调用都有一个同名但不带sys_. 因此,例如,您可以查看man 2 lseek以获取有关以下参数的信息sys_lseek:
off_t lseek(int fd, off_t offset, int whence);
Run Code Online (Sandbox Code Playgroud)
如您所见,其中的参数与 HTML 表中的参数相匹配:
%ebx %ecx %edx
unsigned int off_t unsigned int
Run Code Online (Sandbox Code Playgroud)