我期待了解程序集級別的printf()語句。然而,大部分彙編程序都會執行一些操作,例如調用外部打印函數,這些函數的依賴性由鏈接器添加的其他對象文件滿足。我想知道打印函數內部的系統調用和非常基本的彙編代碼。對於printf,我需要一個彙編代碼,其中唯一的外部調用是系統調用。我在想像一個de組裝的對象文件。我在哪裏可以得到類似的東西?只有系統調用才能在程序集中獲得printf?
回答
我建議改爲先留在C級,然後研究一下Linux上一些現有的C標準庫free software實現的源代碼。查看musl-libc或GNU libc(又名glibc
)的源代碼。你會明白,在printf
和基本系統調用(在syscalls(2) ...中列出)之間有幾個中間(通常是內部)函數是有用的。對printf
(例如,通常的hello-world示例)的樣本C程序也使用strace(1)。
特別是,musl-libc
有一個非常可讀的stdio/printf.c實現,但在到達write(2)系統調用之前,您需要遵循其他幾個C函數。請注意,有些涉及buffering。另見setvbuf(3) & fflush(3)。幾個答案(例如this和that一)解釋功能之間的鏈,如printf
和系統調用(直到內核代碼)。
我想一段彙編代碼,唯一的外線呼叫系統呼叫,
printf
如果你想正是這一點,你可以從MUSL-libc中的stdio/printf.c開始,從musl-libc添加任何額外的源文件,直到你沒有更多的外部未定義的符號,並編譯所有的gcc -flto -O2
或許也-S
,你可能會以對象(或彙編)形式完成大部分musl-libc b因爲printf
可能會呼叫malloc
和許多其他功能!)...我不知道這是值得的痛苦。
您還可以靜態鏈接您的libc
(例如libc.a
)。然後鏈接器將鏈接printf
(以及您調用的任何其他函數)所需的靜態庫成員。
挑剔,system calls實際上並沒有外線電話(你的libc write
函數實際上是圍繞着原始的系統調用一個小包裝)。您可以使用SYSENTER
機器指令來製作它們(但使用vdso(7)更可取:更便攜,也許更快),並且甚至不需要有效的堆棧指針(在x86_64上)來進行系統調用。
您可以編寫Linux用戶級程序,甚至不需要使用libc
; Scheme的bones實現就是這樣一個程序(你會找到其他的)。
函數printf()
位於標準C庫中,所以它被鏈接到您的程序中並且不會複製到它中。動態鏈接庫可節省內存,因爲每個使用它的程序都沒有在常駐內存中複製完全相同的代碼。
想想printf()
的功能。解釋格式化的字符串並生成正確的輸出相當複雜。 printf()
所屬的一系列函數也緩衝輸出。你可能並不是真的想在彙編中重新實現所有這些。標準的C庫是無所不在的,並且可能爲您提供。
也許你正在尋找write(2)
,這是系統調用只緩衝寫入文件描述符的字節。您必須生成預先打印的字符串並自行設置格式。 (也open(2)
打開文件見。)
拆解二進制文件,你可以使用objdump
:
objdump -d binary
其中binary
是一些編譯好的二進制。這給出了操作碼和人類可讀指令。你可能想重定向到一個文件並在別處讀取。
您可以在您的系統上反彙編標準C二進制文件,並嘗試解釋它,如果你想(強烈不推薦)。問題在於它太複雜而難以理解。像printf()
這樣的東西是用C編寫的,然後編譯和彙編。你不能(在合理的幾十年內)從編譯(非平凡)程序的彙編中恢復高級結構。如果你真的想試試這個,祝你好運。
更簡單的做法是查看printf()
本身的C源代碼。真正的工作實際上是在vfprintf()
中完成的,它位於GNU C庫source code的stdio-common/vfprintf.c
中。
我不想重新實現它,我知道它爲什麼這樣做。我只想看看它是如何實現的...... – user2277550
*「在標準的C庫中,所以它被鏈接到你的程序中,而不是複製到它」*不一定是真的。許多較舊的系統將整個運行時間庫鏈接到生成可執行文件。可共享的動態鏈接庫是一個相對較新的創新。由於OP沒有指定任何特定的環境,因此假定現代高效的環境是不準確的。 – wallyk
- 1. 只有在Composer中才有可能獲得/分配?
- 2. 我怎樣才能獲得設備ID爲android系統中
- 3. 如何在Windows的x86程序集中編寫系統調用?
- 4. JQuery只有在選中時才能獲得複選框的值
- 5. 如何獲得調用系統調用的進程的pid?
- 6. 只有前20%的用戶纔有可能獲得Twitter趨勢?
- 7. 系統調用獲得Linux中的機器序列號(用java編程)
- 8. 程序集分析系統()中調用的函數C
- 9. CHDIR系統調用在C程序
- 10. 我怎樣才能在我的程序中獲得_GLOBAL_OFFSET_TABLE_地址?
- 11. 從多線程程序調用系統()
- 12. 爲什麼x86_64程序集有奇怪的系統調用參數順序?
- 13. 有執行程序和調用函數統一的系統嗎?
- 14. fork系統調用的應用程序
- 15. Windows上的Unix應用子系統如何在程序集中實現系統調用?如
- 16. 我怎樣才能在android系統
- 17. 在線程中選擇()系統調用?
- 18. Windows程序的系統調用
- 19. 環路系統調用C程序
- 20. Linux系統調用流程序列號
- 21. .net系統調用性能
- 22. Android應用程序來獲得系統的電話號碼
- 23. 我怎樣才能調用android截圖系統?
- 24. 安裝在android系統/系統/應用程序目錄中的應用程序
- 25. 如何在Cake腳本中引用系統程序集?
- 26. 我們如何才能從數據庫中獲得具有通用處理程序或jquery的數據集
- 27. 只有在引用基類時才能調用的方法? C++
- 28. 如何在運行時獲得ruby系統()調用的STDOUT?
- 29. 我怎樣才能獲得每個進程在Windows操作系統下使用的連接帶寬?
- 30. IA-32程序集cpuid使用printf
在大多數情況下,printf()代碼通過putchar()調用操作系統write()。 –
但是,我怎麼可能反彙編我的Linux上的東西,看看它是怎麼做到的????所以putchar()只是一個write()?? – user2277550