2014-10-17 81 views
-1

我是Linux的新手,用於彙編程序設計(GAS)和英語。所以,如果我寫錯了,抱歉。我希望谷歌翻譯能夠幫到我,寫得不錯。當我編寫系統調用時,Linux會做什麼?

我想知道如何將一組數字(存儲在.data中)寫入文本文件中,而無需調用任何庫中的函數(如printf()),並且只通過彙編程序進行操作。我不想要現成的解決方案。我想知道我的寫入調用後Linux內核的功能。怎麼運行的?它是如何設計的?

我試圖將數字列表打印到STDOUT中,但我在終端中收到奇數號。我認爲這是因爲我不明白如何正確使用寫入系統調用。

這是我得到了現在

.section .data  
list:        .long 12, 31, 42 

.section .text  
.globl _start 
_start: 
movl $4, %eax 
movl $1, %ebx 
movl $list, %ecx 
movl $12, %edx 
int $0x80 
movl $1, %eax 
movl $0, %ebx 
int $0x80 

此代碼工作正常.ascii "Hello world\0",而不是號碼列表。

+0

這是一個令人難以置信的廣泛的主題,需要相當多的背景知識來了解我懷疑你沒有的東西。你可能想把它分解成一些大小的塊,向我們展示你迄今爲止付出的努力以及你被困在哪裏。 – tangrs 2014-10-17 10:52:01

+0

閱讀http://www.tldp.org/HOWTO/Assembly-HOWTO/它是相關的 – 2014-10-20 13:19:15

+0

我讀了Jonathan Bartlett的「從頭開始編程」。哪個更好? – user2422443 2014-10-20 13:31:51

回答

4

首先:

甚至庫函數(例如,來自libc.so)在內部使用系統調用。

系統調用或多或少是CALL指令的特殊變體。該指令將調用某些代碼(如CALL所做的),但它會將CPU置於特權模式(在此模式下,CPU可訪問在用戶模式下無法訪問的地址)以及要調用的函數的地址位於固定位置(由特殊寄存器定義,只能在特權模式下訪問)。

被調用的函數將評估EAX寄存器(假設32位Linux for x86)並執行期望的操作(如果EAX爲4,則執行「寫入」操作)。

超出系統調用的代碼非常非常大且複雜。最後,系統調用將導致將數據寫入例如屬於磁盤驅動器或圖形卡的I/O端口和內存區域。

要將字符寫入屏幕,例如將數據寫入位於未映射地址0xB8000處的圖形存儲器,該地址對應於舊版內核中的映射地址0xC00B8000。

這意味着當屏幕處於文本模式時,將一些數據寫入這樣的地址的「mov」指令將導致屏幕上顯示字符。

但是,只有CPU處於特權模式時才能訪問此地址(0xC00B8000)。否則會引發異常(這也是某種由硬件而不是由軟件引起的「CALL」);在這種情況下調用的例程會打印出「總線錯誤」之類的內容並停止該程序。

---編輯---

關於您編輯的問題:

「寫」系統調用會寫ASCII字符到屏幕或文件。

如果你想寫數字,你必須將數字轉換爲一個ASCII字符序列。

+0

哇!這很複雜。謝謝!我編輯了我的問題,並使其更具體。你可以看看它,並讓我思考方向嗎?我必須理解正確地做到這一點? – user2422443 2014-10-20 13:21:16

+0

知道了!這就是我需要的!非常感謝你! – user2422443 2014-10-20 17:48:17