2016-08-03 52 views
2

當我嘗試研究內核系統調用的返回值時,我找到描述它們的表以及我需要放入不同的寄存器以讓它們工作的表。然而,我沒有找到任何文件,它說什麼是我從系統調用返回的值。我只是在不同的地方發現,我收到的將會在EAX寄存器中。彙編中系統調用的返回值是什麼?


TutorialsPoint

結果通常在EAX寄存器返回。

彙編語言步驟一步:由傑夫Duntemann的Linux書編程在他的計劃指出很多次:

  • 看SYS_READ的返回值在EAX

  • 複製sys_read的安全保存返回值


任何網站我有沒有這個返回值說明的。有沒有互聯網來源?或者有人可以向我解釋這個價值嗎?

+0

嘗試使用Google搜索「sys_read」。這是我發現的東西。 http://asm.sourceforge.net/syscall.html –

+0

@MarkLakata我試過但沒有幫助。正如我所說的,它只是說我需要在不同的寄存器中放入什麼,以便系統調用起作用。 (例如[here](http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html)和[here](http://blog.rchapman.org/post/36801038863/linux -system-call-table-for-x86-64)。) –

+1

如果你的谷歌「sys_read」的第四個鏈接是這樣的:https://lwn.net/Articles/604287/,它有所有的血淋淋的細節。 –

回答

5

另請參閱this excellent LWN article about system calls它承擔C知識。

另外:The Definitive Guide to Linux System Calls (on x86),以及相關:What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?


C是Unix系統的編程語言,因此,所有的文檔都以C的條款,然後在那裏C接口之間的細微差別的文檔和任何給定平臺上的asm,通常在手冊頁的Notes部分。

sys_read表示原始系統調用(與libc包裝函數相反)。 read系統調用的內核實現是一個稱爲sys_read()的內核函數。你不能用call指令調用它,因爲它在內核中,而不是在庫中。但人們仍然在談論「調用sys_read」以區別於libc函數調用。然而,即使你的意思是原始的系統調用(特別是當libc包裝器沒有做任何特別的事情時),也可以說read,就像我在這個答案中做的那樣。

另請注意,syscall.h定義了常量,如SYS_read與實際系統呼叫號碼。 (您在int 0x80syscall指令之前放入EAX的值)。


Linux系統調用的返回值(在EAX在x86/RAX)或者是成功的非負值,或a negative error code。例如如果您傳遞了無效指針,則爲-EFAULT

此行爲記錄在syscalls(2)手冊頁中。

實際上,-1到-4095意味着錯誤,其他意味着成功。 glibc的generic syscall(2) wrapper使用這個序列:cmp rax, -4095/jae SYSCALL_ERROR_LABEL,對於所有的Linux系統調用顯然是guaranteed to be future-proof。有趣的案例包括mmap,其中有效地址爲can have the sign bit set, but must be page alignedgetpriority,其中內核ABI將-20..19的返回值範圍映射到1..40,並由libc對其進行解碼。更多詳情請參閱a related answer about decoding syscall error return values

更新,是它絕對保證所有系統調用-4095 .. -1是Linux運行的所有體系結構上的錯誤範圍。有關更多詳細信息,請參閱AOSP non-obvious syscall() implementation。 (將來,不同的體系結構可以爲MAX_ERRNO使用不同的值,但現有的像x86-64這樣的拱的值可以保持不變,這是Linux保持內核ABI穩定的不間斷用戶空間策略的一部分。 )


要找到常量的實際數值爲特定的平臺,你需要找到C頭文件,他們是#define d。詳情請參閱my answer on a question about that


每個SYS調用的返回值的含義都記錄在第2節手冊頁,像read(2)。 (sys_read是原始系統調用glibc read()函數是一個非常薄的包裝。)大多數手冊頁有一個完整的部分爲返回值。例如

返回值

成功時,字節讀取返回的個數(零表示文件的結束 ),並且該文件的位置由該數目提前。如果這個數字小於請求的字節數 ,則它不是錯誤;這可能會發生,例如因爲更少的字節實際上現在可用(可能是因爲我們接近
文件,或者因爲我們正在從管道或終端讀取)或
因爲讀取()被一個信號中斷。另請參閱註釋。

出錯時,返回-1,並適當設置errno。在此 的情況下,未指定文件位置(如果有)
是否更改。

需要注意的是最後一段描述glibc的包裝如果原始系統調用的返回值是負數如何解碼值和sets errno-EAX,所以errno=EFAULT並返回-1如果原始系統調用返回-EFAULT

還有一整段列出了允許read()返回的所有可能的錯誤代碼,以及它們專門用於read()的含義。 (POSIX將這種行爲的大部分標準化。)


我不知道究竟在何處的glibc解碼返回值mmap(2),這裏的返回值不是一個符號類型。它可能使用與通用的系統調用封裝器相同的方法(檢查無符號值> -4096UL),但每個系統調用的特定封裝器沒有實際混洗寄存器之間的參數和調用該函數的開銷。

我沒有看到它in the glibc source tree;據推測它被埋在了一些宏的層次之下。例如in the x86-64 macro

+0

1. * sys_read *等於'read()'嗎? 2.什麼是'-errno','-EFAULT'和'-retval'?它與Assembly有什麼關係? –

+1

@PichiWuana:1.當然可以。 2. C是Unix系統編程的語言。所有內容都以C語言記錄。 C基本上就是便攜式彙編語言。 ['errno'是一個全局](http://man7.org/linux/man-pages/man3/errno.3.html),它是在任何庫函數遇到錯誤後設置的。 '-'是C一元否定運算符。 'EFAULT'是一個由C預處理器宏定義的整數常量。 'retval'是我編寫的一個變量名,用於描述EAX在系統調用後保留的內容。 –

+0

這是否意味着如果你知道好的彙編程序設計,你會很容易地理解C語言?反之亦然? –

相關問題