Assembly - Zarządzanie plikami
System traktuje dane wejściowe lub wyjściowe jako strumień bajtów. Istnieją trzy standardowe strumienie plików -
- Wejście standardowe (stdin),
- Standardowe wyjście (stdout) i
- Błąd standardowy (stderr).
Deskryptor pliku
ZA file descriptorto 16-bitowa liczba całkowita przypisana do pliku jako identyfikator pliku. Gdy tworzony jest nowy plik lub otwierany jest istniejący plik, do uzyskania dostępu do pliku używany jest deskryptor pliku.
Deskryptor plików standardowych strumieni plików - stdin, stdout i stderr wynoszą odpowiednio 0, 1 i 2.
Wskaźnik pliku
ZA file pointerokreśla lokalizację kolejnej operacji odczytu / zapisu w pliku w bajtach. Każdy plik jest traktowany jako sekwencja bajtów. Każdy otwarty plik jest powiązany ze wskaźnikiem pliku, który określa przesunięcie w bajtach względem początku pliku. Kiedy plik jest otwierany, wskaźnik pliku jest ustawiany na zero.
Wywołania systemowe obsługi plików
Poniższa tabela krótko opisuje wywołania systemowe związane z obsługą plików -
% eax | Nazwa | % 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 |
Kroki wymagane do korzystania z wywołań systemowych są takie same, jak omówiliśmy wcześniej -
- Umieść numer wywołania systemowego w rejestrze EAX.
- Przechowuj argumenty wywołania systemowego w rejestrach EBX, ECX itp.
- Wywołaj odpowiednie przerwanie (80h).
- Wynik jest zwykle zwracany w rejestrze EAX.
Tworzenie i otwieranie pliku
Aby utworzyć i otworzyć plik, wykonaj następujące czynności -
- Umieść wywołanie systemowe sys_creat () numer 8 w rejestrze EAX.
- Umieść nazwę pliku w rejestrze EBX.
- Umieść uprawnienia do plików w rejestrze ECX.
Wywołanie systemowe zwraca deskryptor pliku utworzonego pliku w rejestrze EAX, w przypadku błędu kod błędu znajduje się w rejestrze EAX.
Otwieranie istniejącego pliku
Aby otworzyć istniejący plik, wykonaj następujące czynności -
- Umieść wywołanie systemowe sys_open () numer 5 w rejestrze EAX.
- Umieść nazwę pliku w rejestrze EBX.
- Umieść tryb dostępu do pliku w rejestrze ECX.
- Umieść uprawnienia do plików w rejestrze EDX.
Wywołanie systemowe zwraca deskryptor pliku utworzonego pliku w rejestrze EAX, w przypadku błędu kod błędu znajduje się w rejestrze EAX.
Wśród trybów dostępu do plików najczęściej używane są: tylko do odczytu (0), tylko do zapisu (1) i do odczytu i zapisu (2).
Czytanie z pliku
Aby odczytać z pliku, wykonaj następujące czynności -
Umieść wywołanie systemowe sys_read () numer 3 w rejestrze EAX.
Umieść deskryptor pliku w rejestrze EBX.
Umieść wskaźnik na buforze wejściowym w rejestrze ECX.
Umieść rozmiar bufora, tj. Liczbę bajtów do odczytania, w rejestrze EDX.
Wywołanie systemowe zwraca liczbę bajtów odczytanych w rejestrze EAX, w przypadku błędu kod błędu znajduje się w rejestrze EAX.
Zapisywanie do pliku
Aby zapisać do pliku, wykonaj następujące czynności -
Umieść wywołanie systemowe sys_write () numer 4 w rejestrze EAX.
Umieść deskryptor pliku w rejestrze EBX.
Umieść wskaźnik na buforze wyjściowym w rejestrze ECX.
Umieść rozmiar bufora, tj. Liczbę bajtów do zapisania, w rejestrze EDX.
Wywołanie systemowe zwraca rzeczywistą liczbę bajtów zapisanych w rejestrze EAX, w przypadku błędu kod błędu znajduje się w rejestrze EAX.
Zamykanie pliku
Aby zamknąć plik, wykonaj następujące czynności -
- Umieść wywołanie systemowe sys_close () numer 6 w rejestrze EAX.
- Umieść deskryptor pliku w rejestrze EBX.
W przypadku błędu wywołanie systemowe zwraca kod błędu w rejestrze EAX.
Aktualizacja pliku
Aby zaktualizować plik, wykonaj następujące czynności -
- Umieść wywołanie systemowe sys_lseek () numer 19 w rejestrze EAX.
- Umieść deskryptor pliku w rejestrze EBX.
- Umieść wartość przesunięcia w rejestrze ECX.
- Umieść punkt odniesienia dla przesunięcia w rejestrze EDX.
Punktem odniesienia mogłoby być:
- Początek pliku - wartość 0
- Aktualna pozycja - wartość 1
- Koniec pliku - wartość 2
W przypadku błędu wywołanie systemowe zwraca kod błędu w rejestrze EAX.
Przykład
Poniższy program tworzy i otwiera plik o nazwie myfile.txt i zapisuje tekst „Welcome to Tutorials Point” w tym pliku. Następnie program odczytuje z pliku i zapisuje dane w buforze o nazwie info . Na koniec wyświetla tekst zapisany w 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
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Written to file
Welcome to Tutorials Point