我有下面的代码打开一个文件,将其读入缓冲区,然后关闭该文件。
关闭文件系统调用要求文件描述符号在ebx寄存器中。ebx寄存器在进行读取系统调用之前获取文件描述符号。我的问题是,在进行读取系统调用之前,我应该将ebx寄存器保存在堆栈中还是某处(int 80h是否可以丢弃ebx寄存器?)。然后恢复ebx寄存器以关闭系统调用?还是我下面的代码安全无虞?
我已经运行了下面的代码并且可以正常工作,我只是不确定是否通常被认为是良好的汇编习惯,因为在int 80h读取调用之前我没有保存ebx寄存器。
;; open up the input file mov eax,5 ; open file system call number mov ebx,[esp+8] ; null terminated string file name, first command line parameter mov ecx,0o ; access type: O_RDONLY int 80h ; file handle or negative error number put in eax test eax,eax js Error ; test sign flag (SF) for negative number which signals error ;; read in the full input file mov ebx,eax ; assign input file descripter mov eax,3 ; read system call number mov ecx,InputBuff ; buffer to read into mov edx,INPUT_BUFF_LEN ; total bytes to read int 80h test eax,eax js Error ; if eax is negative then error jz Error ; if no bytes were read then error add eax,InputBuff ; add size of input to the begining of InputBuff location mov [InputEnd],eax ; assign address of end of input ;; close the input file ;; file descripter is already in ebx mov eax,6 ; close file system call number int 80h
该int 80h调用本身不会破坏任何东西,除了把返回值eax。因此,您拥有的代码片段很好。(但是,如果您的代码片段是一个更大的例程的一部分,而该例程预期会被通常的Linux x86 ABI之后的其他代码调用,则您需要ebx在进入例程时保留,可能还有其他寄存器,并在退出时进行恢复。 )
int 80h
eax
ebx
内核中的相关代码可以在中找到arch/x86/kernel/entry_32.S。由于宏的广泛使用和各种详细信息(支持syscall跟踪,DWARF调试注释等),因此很难遵循;但是:int 80h处理程序是system_call(我链接到的版本的493行);寄存器通过SAVE_ALL宏保存(第497行);并RESTORE_REGS在返回之前再次通过(第534行)将其恢复。
arch/x86/kernel/entry_32.S
system_call
SAVE_ALL
RESTORE_REGS