x86汇编:让Linux的系统调用你应该保存所有寄存器之前? [英] x86 Assembly: Before Making a System Call on Linux Should You Save All Registers?

查看:279
本文介绍了x86汇编:让Linux的系统调用你应该保存所有寄存器之前?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经打开了一个文件,下面的code,读入缓冲区,然后关闭该文件。

关闭文件系统调用需要的文件描述符在EBX寄存器。 EBX寄存器得到读取系统调用之前的文件描述符号。我的问题是我要救EBX寄存器堆栈上或其他地方之前,我做read系统调用,(可以诠释80H垃圾EBX寄存器?)。然后恢复EBX寄存器为close系统调用?或者是code我有以下罚款和安全?

我已运行低于code和它的作品,我只是不知道,如果它被普遍认为是良好的装配练习或不是因为我不救INT 80H读取调用之前EBX寄存器。

  ;;打开输入文件
MOV EAX,5;打开文件系统调用号
MOV EBX,[ESP + 8];空结尾的字符串的文件名,第一个命令行参数
MOV ECX,0°;访问类型:O_RDONLY
INT 80H;把文件句柄或负的错误数目EAX
TEST EAX,EAX
JS错误;这标志着误码测试符号标志(SF)为负数;;阅读完整的输入文件
MOV EBX,EAX;指定输入文件的描述符
MOV EAX,3;读取系统调用号
MOV ECX,InputBuff;缓冲器读入
MOV EDX,INPUT_BUFF_LEN;总字节数读
INT 80H
TEST EAX,EAX
JS错误;如果EAX为负,那么错误
JZ错误;如果没有字节读了那么错误
添加EAX,InputBuff;加输入的大小以InputBuff位置的开头
MOV [InputEnd],EAX;分配输入端的地址;;关闭输入文件
;;文件描述符已经在EBX
MOV EAX,6;关闭文件系统调用号
INT 80H


解决方案

INT 80H 称自己不会破坏任何东西,除了把返回值 EAX 。所以,你有code片段是罚款。 (但如果你的code片段是预计将通过其他code以下通常的Linux的x86 ABI被称为一个更大的日常工作​​的一部分,你需要preserve EBX ,和其他可能的寄存器,在进入到你的日常,并在退出恢复。)

在内核中的相关code可以在的 弓/ 86 /内核/ entry_32.S 。这是一个有点难以遵循,由于大量使用宏,以及各种细节(对于系统调用跟踪,矮人调试注释等支持),但:在 INT 80H 处理程序 system_call的(在我挂线版493);该寄存器通过 SAVE_ALL 宏保存(线路497);他们正在通过 RESTORE_REGS 又恢复(行534)之前回来了。

I have the below code that opens up a file, reads it into a buffer and then closes the file.

The close file system call requires that the file descriptor number be in the ebx register. The ebx register gets the file descriptor number before the read system call is made. My question is should I save the ebx register on the stack or somewhere before I make the read system call, (could int 80h trash the ebx register?). And then restore the ebx register for the close system call? Or is the code I have below fine and safe?

I have run the below code and it works, I'm just not sure if it is generally considered good assembly practice or not because I don't save the ebx register before the int 80h read call.

;; 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         

解决方案

The int 80h call itself will not corrupt anything, apart from putting the return value in eax. So the code fragment you have is fine. (But if your code fragment is part of a larger routine which is expected to be called by other code following the usual Linux x86 ABI, you will need to preserve ebx, and possibly other registers, on entry to your routine, and restore on exit.)

The relevant code in the kernel can be found in arch/x86/kernel/entry_32.S. It's a bit hard to follow, due to extensive use of macros, and various details (support for syscall tracing, DWARF debugging annotations, etc.) but: the int 80h handler is system_call (line 493 in the version I've linked to); the registers are saved via the SAVE_ALL macro (line 497); and they're restored again via RESTORE_REGS (line 534) just before returning.

这篇关于x86汇编:让Linux的系统调用你应该保存所有寄存器之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆