
彙編 - 檔案管理
系統將任何輸入或輸出資料視為位元組流。存在三個標準檔案流:
- 標準輸入 (stdin),
- 標準輸出 (stdout), 和
- 標準錯誤 (stderr).
檔案描述符
檔案描述符是一個分配給檔案的16位整數,作為檔案的ID。當建立一個新檔案或開啟一個現有檔案時,檔案描述符用於訪問該檔案。
標準檔案流stdin,stdout和stderr的檔案描述符分別為0、1和2。
檔案指標
檔案指標以位元組為單位指定檔案中後續讀/寫操作的位置。每個檔案都被視為位元組序列。每個開啟的檔案都與一個檔案指標相關聯,該檔案指標指定相對於檔案開頭的位元組偏移量。開啟檔案時,檔案指標設定為零。
檔案處理系統呼叫
下表簡要描述了與檔案處理相關的系統呼叫:
%eax | 名稱 | %ebx | %ecx | %edx |
---|---|---|---|---|
2 | sys_fork | struct pt_regs | - | - |
3 | sys_read | unsigned int | char * | size_t |
4 | sys_write | unsigned int | const char * | size_t |
5 | sys_open | const char * | int | int |
6 | sys_close | unsigned int | - | - |
8 | sys_creat | const char * | int | - |
19 | sys_lseek | unsigned int | off_t | unsigned int |
使用系統呼叫的步驟與我們前面討論的一樣:
- 將系統呼叫號放入EAX暫存器。
- 將引數儲存到EBX、ECX等暫存器中的系統呼叫。
- 呼叫相關的中斷 (80h)。
- 結果通常返回到EAX暫存器。
建立和開啟檔案
要建立和開啟檔案,請執行以下任務:
- 將系統呼叫sys_creat()編號8放入EAX暫存器。
- 將檔名放入EBX暫存器。
- 將檔案許可權放入ECX暫存器。
系統呼叫在EAX暫存器中返回已建立檔案的描述符,如果出錯,則EAX暫存器中為錯誤程式碼。
開啟現有檔案
要開啟現有檔案,請執行以下任務:
- 將系統呼叫sys_open()編號5放入EAX暫存器。
- 將檔名放入EBX暫存器。
- 將檔案訪問模式放入ECX暫存器。
- 將檔案許可權放入EDX暫存器。
系統呼叫在EAX暫存器中返回已建立檔案的描述符,如果出錯,則EAX暫存器中為錯誤程式碼。
在檔案訪問模式中,最常用的是:只讀(0)、只寫(1)和讀寫(2)。
從檔案讀取
要從檔案讀取,請執行以下任務:
將系統呼叫sys_read()編號3放入EAX暫存器。
將檔案描述符放入EBX暫存器。
將指向輸入緩衝區的指標放入ECX暫存器。
將緩衝區大小(即要讀取的位元組數)放入EDX暫存器。
系統呼叫在EAX暫存器中返回讀取的位元組數,如果出錯,則EAX暫存器中為錯誤程式碼。
寫入檔案
要寫入檔案,請執行以下任務:
將系統呼叫sys_write()編號4放入EAX暫存器。
將檔案描述符放入EBX暫存器。
將指向輸出緩衝區的指標放入ECX暫存器。
將緩衝區大小(即要寫入的位元組數)放入EDX暫存器。
系統呼叫在EAX暫存器中返回實際寫入的位元組數,如果出錯,則EAX暫存器中為錯誤程式碼。
關閉檔案
要關閉檔案,請執行以下任務:
- 將系統呼叫sys_close()編號6放入EAX暫存器。
- 將檔案描述符放入EBX暫存器。
系統呼叫返回,如果出錯,則EAX暫存器中為錯誤程式碼。
更新檔案
要更新檔案,請執行以下任務:
- 將系統呼叫sys_lseek()編號19放入EAX暫存器。
- 將檔案描述符放入EBX暫存器。
- 將偏移值放入ECX暫存器。
- 將偏移量的參考位置放入EDX暫存器。
參考位置可以是
- 檔案開頭 - 值0
- 當前位置 - 值1
- 檔案結尾 - 值2
系統呼叫返回,如果出錯,則EAX暫存器中為錯誤程式碼。
示例
下面的程式建立一個名為myfile.txt的檔案並開啟它,然後在這個檔案中寫入文字“歡迎來到 Tutorials Point”。接下來,程式從檔案中讀取資料並將其儲存到名為info的緩衝區中。最後,它顯示儲存在info中的文字。
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point ;create the file mov eax, 8 mov ebx, file_name mov ecx, 0777 ;read, write and execute by all int 0x80 ;call kernel mov [fd_out], eax ; write into the file mov edx,len ;number of bytes mov ecx, msg ;message to write mov ebx, [fd_out] ;file descriptor mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel ; close the file mov eax, 6 mov ebx, [fd_out] ; write the message indicating end of file write mov eax, 4 mov ebx, 1 mov ecx, msg_done mov edx, len_done int 0x80 ;open the file for reading mov eax, 5 mov ebx, file_name mov ecx, 0 ;for read only access mov edx, 0777 ;read, write and execute by all int 0x80 mov [fd_in], eax ;read from file mov eax, 3 mov ebx, [fd_in] mov ecx, info mov edx, 26 int 0x80 ; close the file mov eax, 6 mov ebx, [fd_in] int 0x80 ; print the info mov eax, 4 mov ebx, 1 mov ecx, info mov edx, 26 int 0x80 mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data file_name db 'myfile.txt' msg db 'Welcome to Tutorials Point' len equ $-msg msg_done db 'Written to file', 0xa len_done equ $-msg_done section .bss fd_out resb 1 fd_in resb 1 info resb 26
編譯並執行上述程式碼後,將產生以下結果:
Written to file Welcome to Tutorials Point