一尘不染

x86 Assembly:在Linux上进行系统调用之前,应该保存所有寄存器吗?

linux

我有下面的代码打开一个文件,将其读入缓冲区,然后关闭该文件。

关闭文件系统调用要求文件描述符号在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

阅读 249

收藏
2020-06-03

共1个答案

一尘不染

int 80h调用本身不会破坏任何东西,除了把返回值eax。因此,您拥有的代码片段很好。(但是,如果您的代码片段是一个更大的例程的一部分,而该例程预期会被通常的Linux
x86 ABI之后的其他代码调用,则您需要ebx在进入例程时保留,可能还有其他寄存器,并在退出时进行恢复。 )

内核中的相关代码可以在中找到arch/x86/kernel/entry_32.S。由于宏的广泛使用和各种详细信息(支持syscall跟踪,DWARF调试注释等),因此很难遵循;但是:int 80h处理程序是system_call(我链接到的版本的493行);寄存器通过SAVE_ALL宏保存(第497行);并RESTORE_REGS在返回之前再次通过(第534行)将其恢复。

2020-06-03