大会,你好世界问题

时间:2010-07-30 23:47:21

标签: assembly x86 linux-kernel system-calls

我在Linux上学习asm(noobuntu 10.04) 我收到了以下代码:http://asm.sourceforge.net/intro/hello.html

section .text
global _start ;must be declared for linker (ld)

_start: ;tell linker entry point

mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel

mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel

section .data

msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string

这是一个简单的问候世界。 Linux +上的运行直接调用内核(显然)。 有谁能解释一下这里到底发生了什么?我认为它读取了eax&中的整数。 ebx处理器寄存器& ecx,edx数据和定义调用内核时的系统调用。如果是这样,当调用int 0x80时,不同的整数组合是否定义了不同的系统调用?

我对手册页不太满意,但已阅读我能找到的每一个相关内容,是否有任何手册页告诉我哪些组合定义了什么系统调用?

感谢任何帮助。一行一行的解释会很棒...... -提前致谢 杰里米

3 个答案:

答案 0 :(得分:7)

当您调用int 0x80时,内核会查看eax寄存器的值以确定您要调用的函数(这是“系统调用号”)。根据该数字,其余的寄存器被解释为具体的事物。 sys_write调用期望寄存器设置如下:

  • eax包含4
  • ebx包含文件描述符
  • ecx包含要写入的数据的地址
  • edx包含字节数

有关更多详细信息,请参阅Linux System Calls

答案 1 :(得分:2)

section .text
global _start ;must be declared for linker (ld)

这只是标题材料,汇编程序的“文本”部分只是机器指令(与数据,只读数据和BSS部分相对)。 global行类似于_start函数是“公开”。

_start: ;tell linker entry point

mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel

从评论中我们知道我们正在查看sys_write函数,因此我们可以man 2 write获取详细信息。 C原型提供以下参数:fd*bufcount。从%ebx开始,我们看到那些匹配(%ebx = fd,%ecx =要写入的字符串,%edx =字符串的长度)。然后,由于我们是一个用户进程,我们必须要求内核执行输出。这是通过SYSCALL接口完成的,write()函数(显然)给出了数字4. INT 0x80是一个调用Linux内核的SYSCALL例程的软件中断。

您可以在Linux头文件中找到所有系统调用的实际数量(假设您已安装它们)。在我的系统上,我检查了/usr/include/sys/syscall.h,导致/usr/include/asm/unistd.h,然后检查了/usr/include/asm-i386/unistd.h。在哪里(我看),#define __NR_write 4

mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel

与前一段的最后两行一样,这只是加载系统调用ID并执行软件中断以退出程序(删除它的内存映射和清理)。

section .data

msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string

这是数据部分,它只描述了我们在程序中使用的变量。

答案 2 :(得分:0)

系统调用太多,每个系统调用都有不同的汇编语言指令。

而是调用TRAP指令。 eax的值确定将调用哪个系统调用。其他寄存器是系统调用的参数。

系统调用列在内核中。