section .data
usage db "Usage: ./caesar {input_file} {output_file} {shift}", 10, 0
len_usage equ $ - usage ; Подсчитываем длину строки usage
error_open_in db "Error: Cannot open input file.", 10, 0
len_error_open_in equ $ - error_open_in ; Подсчитываем длину строки error_open_in
error_open_out db "Error: Cannot open output file.", 10, 0
len_error_open_out equ $ - error_open_out ; Подсчитываем длину строки error_open_out
section .bss
bytes_read resd 1
bytes_written resd 1
buffer resb 1024 ; Буфер для чтения
buffer_size equ 1024 ; Размер буфера
section .text
global _start
_start:
; Проверка количества аргументов
mov eax, dword [esp+4] ; argc
cmp eax, 4 ; argc должно быть 4
je process_args
; Вывод использования программы
mov eax, 4 ; sys_write
mov ebx, 1 ; stdout
mov ecx, usage ; Адрес строки
mov edx, len_usage ; Длина строки
int 0x80 ; Вызов ядра
jmp exit
process_args:
; Получение параметров
mov ebx, dword [esp+8] ; argv[1] (input_file)
mov ecx, dword [esp+12] ; argv[2] (output_file)
mov edx, dword [esp+16] ; argv[3] (shift)
; Открыть входной файл
mov eax, 5 ; sys_open
mov edi, ebx ; input_file
mov esi, 0 ; O_RDONLY
int 0x80
cmp eax, 0 ; Проверка ошибки
jl error_open_input
mov ebx, eax ; Сохраняем дескриптор входного файла
; Открыть выходной файл
mov eax, 5 ; sys_open
mov edi, ecx ; output_file
mov esi, 578 ; O_WRONLY | O_CREAT | O_TRUNC (0666)
mov ebp, 0666 ; Права доступа
int 0x80
cmp eax, 0 ; Проверка ошибки
jl error_open_output
mov ecx, eax ; Сохраняем дескриптор выходного файла
; Получить сдвиг
mov eax, edx ; shift
sub eax, '0' ; Преобразуем ASCII в число
mov edx, eax ; Сохраняем сдвиг в edx
read_loop:
; Чтение из входного файла
mov eax, 3 ; sys_read
mov ebx, ebx ; Дескриптор входного файла
mov ecx, buffer ; Буфер для чтения
mov edx, buffer_size ; Размер буфера
int 0x80
cmp eax, 0 ; EOF или ошибка
jle close_files
mov dword [bytes_read], eax
; Обработка данных
mov esi, buffer ; Указатель на буфер
mov ecx, dword [bytes_read] ; Количество прочитанных байт
process_char:
mov al, byte [esi] ; Получить символ
cmp al, 'A' ; Проверить верхний регистр
jb skip_char
cmp al, 'Z'
ja check_lower
; Верхний регистр
sub al, 'A'
mov ebx, 26 ; Делитель для циклического сдвига
div bl ; Делим на 26
add al, 'A'
jmp store_char
check_lower:
cmp al, 'a'
jb skip_char
cmp al, 'z'
ja skip_char
; Нижний регистр
sub al, 'a'
mov ebx, 26 ; Делитель для циклического сдвига
div bl ; Делим на 26
add al, 'a'
store_char:
mov byte [esi], al ; Сохранить символ
skip_char:
inc esi
loop process_char
; Запись в выходной файл
mov eax, 4 ; sys_write
mov ebx, ecx ; Дескриптор выходного файла
mov ecx, buffer ; Буфер для записи
mov edx, dword [bytes_read] ; Количество записываемых байт
int 0x80
jmp read_loop
close_files:
; Закрытие файлов
mov eax, 6 ; sys_close
mov ebx, ebx ; Закрываем входной файл
int 0x80
mov eax, 6 ; sys_close
mov ebx, ecx ; Закрываем выходной файл
int 0x80
exit:
mov eax, 1 ; sys_exit
xor ebx, ebx ; Код возврата 0
int 0x80
error_open_input:
mov eax, 4 ; sys_write
mov ebx, 1 ; stdout
mov ecx, error_open_in ; Сообщение об ошибке
mov edx, len_error_open_in ; Длина сообщения
int 0x80
jmp exit
error_open_output:
mov eax, 4 ; sys_write
mov ebx, 1 ; stdout
mov ecx, error_open_out ; Сообщение об ошибке
mov edx, len_error_open_out ; Длина сообщения
int 0x80
jmp exit
c2VjdGlvbiAuZGF0YQogICAgdXNhZ2UgZGIgIlVzYWdlOiAuL2NhZXNhciB7aW5wdXRfZmlsZX0ge291dHB1dF9maWxlfSB7c2hpZnR9IiwgMTAsIDAKICAgIGxlbl91c2FnZSBlcXUgJCAtIHVzYWdlICA7INCf0L7QtNGB0YfQuNGC0YvQstCw0LXQvCDQtNC70LjQvdGDINGB0YLRgNC+0LrQuCB1c2FnZQoKICAgIGVycm9yX29wZW5faW4gZGIgIkVycm9yOiBDYW5ub3Qgb3BlbiBpbnB1dCBmaWxlLiIsIDEwLCAwCiAgICBsZW5fZXJyb3Jfb3Blbl9pbiBlcXUgJCAtIGVycm9yX29wZW5faW4gIDsg0J/QvtC00YHRh9C40YLRi9Cy0LDQtdC8INC00LvQuNC90YMg0YHRgtGA0L7QutC4IGVycm9yX29wZW5faW4KCiAgICBlcnJvcl9vcGVuX291dCBkYiAiRXJyb3I6IENhbm5vdCBvcGVuIG91dHB1dCBmaWxlLiIsIDEwLCAwCiAgICBsZW5fZXJyb3Jfb3Blbl9vdXQgZXF1ICQgLSBlcnJvcl9vcGVuX291dCAgOyDQn9C+0LTRgdGH0LjRgtGL0LLQsNC10Lwg0LTQu9C40L3RgyDRgdGC0YDQvtC60LggZXJyb3Jfb3Blbl9vdXQKCnNlY3Rpb24gLmJzcwogICAgYnl0ZXNfcmVhZCByZXNkIDEKICAgIGJ5dGVzX3dyaXR0ZW4gcmVzZCAxCiAgICBidWZmZXIgcmVzYiAxMDI0ICAgICAgICAgICAgICAgOyDQkdGD0YTQtdGAINC00LvRjyDRh9GC0LXQvdC40Y8KICAgIGJ1ZmZlcl9zaXplIGVxdSAxMDI0ICAgICAgICAgICA7INCg0LDQt9C80LXRgCDQsdGD0YTQtdGA0LAKCnNlY3Rpb24gLnRleHQKICAgIGdsb2JhbCBfc3RhcnQKCl9zdGFydDoKICAgIDsg0J/RgNC+0LLQtdGA0LrQsCDQutC+0LvQuNGH0LXRgdGC0LLQsCDQsNGA0LPRg9C80LXQvdGC0L7QsgogICAgbW92IGVheCwgZHdvcmQgW2VzcCs0XSAgICAgICAgIDsgYXJnYwogICAgY21wIGVheCwgNCAgICAgICAgICAgICAgICAgICAgIDsgYXJnYyDQtNC+0LvQttC90L4g0LHRi9GC0YwgNAogICAgamUgcHJvY2Vzc19hcmdzCgogICAgOyDQktGL0LLQvtC0INC40YHQv9C+0LvRjNC30L7QstCw0L3QuNGPINC/0YDQvtCz0YDQsNC80LzRiwogICAgbW92IGVheCwgNCAgICAgICAgICAgICAgICAgICAgIDsgc3lzX3dyaXRlCiAgICBtb3YgZWJ4LCAxICAgICAgICAgICAgICAgICAgICAgOyBzdGRvdXQKICAgIG1vdiBlY3gsIHVzYWdlICAgICAgICAgICAgICAgICA7INCQ0LTRgNC10YEg0YHRgtGA0L7QutC4CiAgICBtb3YgZWR4LCBsZW5fdXNhZ2UgICAgICAgICAgICAgOyDQlNC70LjQvdCwINGB0YLRgNC+0LrQuAogICAgaW50IDB4ODAgICAgICAgICAgICAgICAgICAgICAgIDsg0JLRi9C30L7QsiDRj9C00YDQsAogICAgam1wIGV4aXQKCnByb2Nlc3NfYXJnczoKICAgIDsg0J/QvtC70YPRh9C10L3QuNC1INC/0LDRgNCw0LzQtdGC0YDQvtCyCiAgICBtb3YgZWJ4LCBkd29yZCBbZXNwKzhdICAgICAgICAgOyBhcmd2WzFdIChpbnB1dF9maWxlKQogICAgbW92IGVjeCwgZHdvcmQgW2VzcCsxMl0gICAgICAgIDsgYXJndlsyXSAob3V0cHV0X2ZpbGUpCiAgICBtb3YgZWR4LCBkd29yZCBbZXNwKzE2XSAgICAgICAgOyBhcmd2WzNdIChzaGlmdCkKCiAgICA7INCe0YLQutGA0YvRgtGMINCy0YXQvtC00L3QvtC5INGE0LDQudC7CiAgICBtb3YgZWF4LCA1ICAgICAgICAgICAgICAgICAgICAgOyBzeXNfb3BlbgogICAgbW92IGVkaSwgZWJ4ICAgICAgICAgICAgICAgICAgIDsgaW5wdXRfZmlsZQogICAgbW92IGVzaSwgMCAgICAgICAgICAgICAgICAgICAgIDsgT19SRE9OTFkKICAgIGludCAweDgwCiAgICBjbXAgZWF4LCAwICAgICAgICAgICAgICAgICAgICAgOyDQn9GA0L7QstC10YDQutCwINC+0YjQuNCx0LrQuAogICAgamwgZXJyb3Jfb3Blbl9pbnB1dAogICAgbW92IGVieCwgZWF4ICAgICAgICAgICAgICAgICAgIDsg0KHQvtGF0YDQsNC90Y/QtdC8INC00LXRgdC60YDQuNC/0YLQvtGAINCy0YXQvtC00L3QvtCz0L4g0YTQsNC50LvQsAoKICAgIDsg0J7RgtC60YDRi9GC0Ywg0LLRi9GF0L7QtNC90L7QuSDRhNCw0LnQuwogICAgbW92IGVheCwgNSAgICAgICAgICAgICAgICAgICAgIDsgc3lzX29wZW4KICAgIG1vdiBlZGksIGVjeCAgICAgICAgICAgICAgICAgICA7IG91dHB1dF9maWxlCiAgICBtb3YgZXNpLCA1NzggICAgICAgICAgICAgICAgICAgOyBPX1dST05MWSB8IE9fQ1JFQVQgfCBPX1RSVU5DICgwNjY2KQogICAgbW92IGVicCwgMDY2NiAgICAgICAgICAgICAgICAgIDsg0J/RgNCw0LLQsCDQtNC+0YHRgtGD0L/QsAogICAgaW50IDB4ODAKICAgIGNtcCBlYXgsIDAgICAgICAgICAgICAgICAgICAgICA7INCf0YDQvtCy0LXRgNC60LAg0L7RiNC40LHQutC4CiAgICBqbCBlcnJvcl9vcGVuX291dHB1dAogICAgbW92IGVjeCwgZWF4ICAgICAgICAgICAgICAgICAgIDsg0KHQvtGF0YDQsNC90Y/QtdC8INC00LXRgdC60YDQuNC/0YLQvtGAINCy0YvRhdC+0LTQvdC+0LPQviDRhNCw0LnQu9CwCgogICAgOyDQn9C+0LvRg9GH0LjRgtGMINGB0LTQstC40LMKICAgIG1vdiBlYXgsIGVkeCAgICAgICAgICAgICAgICAgICA7IHNoaWZ0CiAgICBzdWIgZWF4LCAnMCcgICAgICAgICAgICAgICAgICAgOyDQn9GA0LXQvtCx0YDQsNC30YPQtdC8IEFTQ0lJINCyINGH0LjRgdC70L4KICAgIG1vdiBlZHgsIGVheCAgICAgICAgICAgICAgICAgICA7INCh0L7RhdGA0LDQvdGP0LXQvCDRgdC00LLQuNCzINCyIGVkeAoKcmVhZF9sb29wOgogICAgOyDQp9GC0LXQvdC40LUg0LjQtyDQstGF0L7QtNC90L7Qs9C+INGE0LDQudC70LAKICAgIG1vdiBlYXgsIDMgICAgICAgICAgICAgICAgICAgICA7IHN5c19yZWFkCiAgICBtb3YgZWJ4LCBlYnggICAgICAgICAgICAgICAgICAgOyDQlNC10YHQutGA0LjQv9GC0L7RgCDQstGF0L7QtNC90L7Qs9C+INGE0LDQudC70LAKICAgIG1vdiBlY3gsIGJ1ZmZlciAgICAgICAgICAgICAgICA7INCR0YPRhNC10YAg0LTQu9GPINGH0YLQtdC90LjRjwogICAgbW92IGVkeCwgYnVmZmVyX3NpemUgICAgICAgICAgIDsg0KDQsNC30LzQtdGAINCx0YPRhNC10YDQsAogICAgaW50IDB4ODAKICAgIGNtcCBlYXgsIDAgICAgICAgICAgICAgICAgICAgICA7IEVPRiDQuNC70Lgg0L7RiNC40LHQutCwCiAgICBqbGUgY2xvc2VfZmlsZXMKICAgIG1vdiBkd29yZCBbYnl0ZXNfcmVhZF0sIGVheAoKICAgIDsg0J7QsdGA0LDQsdC+0YLQutCwINC00LDQvdC90YvRhQogICAgbW92IGVzaSwgYnVmZmVyICAgICAgICAgICAgICAgIDsg0KPQutCw0LfQsNGC0LXQu9GMINC90LAg0LHRg9GE0LXRgAogICAgbW92IGVjeCwgZHdvcmQgW2J5dGVzX3JlYWRdICAgIDsg0JrQvtC70LjRh9C10YHRgtCy0L4g0L/RgNC+0YfQuNGC0LDQvdC90YvRhSDQsdCw0LnRggpwcm9jZXNzX2NoYXI6CiAgICBtb3YgYWwsIGJ5dGUgW2VzaV0gICAgICAgICAgICAgOyDQn9C+0LvRg9GH0LjRgtGMINGB0LjQvNCy0L7QuwogICAgY21wIGFsLCAnQScgICAgICAgICAgICAgICAgICAgIDsg0J/RgNC+0LLQtdGA0LjRgtGMINCy0LXRgNGF0L3QuNC5INGA0LXQs9C40YHRgtGACiAgICBqYiBza2lwX2NoYXIKICAgIGNtcCBhbCwgJ1onCiAgICBqYSBjaGVja19sb3dlcgogICAgOyDQktC10YDRhdC90LjQuSDRgNC10LPQuNGB0YLRgAogICAgc3ViIGFsLCAnQScKICAgIG1vdiBlYngsIDI2ICAgICAgICAgICAgICAgICAgICA7INCU0LXQu9C40YLQtdC70Ywg0LTQu9GPINGG0LjQutC70LjRh9C10YHQutC+0LPQviDRgdC00LLQuNCz0LAKICAgIGRpdiBibCAgICAgICAgICAgICAgICAgICAgICAgICA7INCU0LXQu9C40Lwg0L3QsCAyNgogICAgYWRkIGFsLCAnQScKICAgIGptcCBzdG9yZV9jaGFyCmNoZWNrX2xvd2VyOgogICAgY21wIGFsLCAnYScKICAgIGpiIHNraXBfY2hhcgogICAgY21wIGFsLCAneicKICAgIGphIHNraXBfY2hhcgogICAgOyDQndC40LbQvdC40Lkg0YDQtdCz0LjRgdGC0YAKICAgIHN1YiBhbCwgJ2EnCiAgICBtb3YgZWJ4LCAyNiAgICAgICAgICAgICAgICAgICAgOyDQlNC10LvQuNGC0LXQu9GMINC00LvRjyDRhtC40LrQu9C40YfQtdGB0LrQvtCz0L4g0YHQtNCy0LjQs9CwCiAgICBkaXYgYmwgICAgICAgICAgICAgICAgICAgICAgICAgOyDQlNC10LvQuNC8INC90LAgMjYKICAgIGFkZCBhbCwgJ2EnCnN0b3JlX2NoYXI6CiAgICBtb3YgYnl0ZSBbZXNpXSwgYWwgICAgICAgICAgICAgOyDQodC+0YXRgNCw0L3QuNGC0Ywg0YHQuNC80LLQvtC7CnNraXBfY2hhcjoKICAgIGluYyBlc2kKICAgIGxvb3AgcHJvY2Vzc19jaGFyCgogICAgOyDQl9Cw0L/QuNGB0Ywg0LIg0LLRi9GF0L7QtNC90L7QuSDRhNCw0LnQuwogICAgbW92IGVheCwgNCAgICAgICAgICAgICAgICAgICAgIDsgc3lzX3dyaXRlCiAgICBtb3YgZWJ4LCBlY3ggICAgICAgICAgICAgICAgICAgOyDQlNC10YHQutGA0LjQv9GC0L7RgCDQstGL0YXQvtC00L3QvtCz0L4g0YTQsNC50LvQsAogICAgbW92IGVjeCwgYnVmZmVyICAgICAgICAgICAgICAgIDsg0JHRg9GE0LXRgCDQtNC70Y8g0LfQsNC/0LjRgdC4CiAgICBtb3YgZWR4LCBkd29yZCBbYnl0ZXNfcmVhZF0gICAgOyDQmtC+0LvQuNGH0LXRgdGC0LLQviDQt9Cw0L/QuNGB0YvQstCw0LXQvNGL0YUg0LHQsNC50YIKICAgIGludCAweDgwCiAgICBqbXAgcmVhZF9sb29wCgpjbG9zZV9maWxlczoKICAgIDsg0JfQsNC60YDRi9GC0LjQtSDRhNCw0LnQu9C+0LIKICAgIG1vdiBlYXgsIDYgICAgICAgICAgICAgICAgICAgICA7IHN5c19jbG9zZQogICAgbW92IGVieCwgZWJ4ICAgICAgICAgICAgICAgICAgIDsg0JfQsNC60YDRi9Cy0LDQtdC8INCy0YXQvtC00L3QvtC5INGE0LDQudC7CiAgICBpbnQgMHg4MAogICAgbW92IGVheCwgNiAgICAgICAgICAgICAgICAgICAgIDsgc3lzX2Nsb3NlCiAgICBtb3YgZWJ4LCBlY3ggICAgICAgICAgICAgICAgICAgOyDQl9Cw0LrRgNGL0LLQsNC10Lwg0LLRi9GF0L7QtNC90L7QuSDRhNCw0LnQuwogICAgaW50IDB4ODAKCmV4aXQ6CiAgICBtb3YgZWF4LCAxICAgICAgICAgICAgICAgICAgICAgOyBzeXNfZXhpdAogICAgeG9yIGVieCwgZWJ4ICAgICAgICAgICAgICAgICAgIDsg0JrQvtC0INCy0L7Qt9Cy0YDQsNGC0LAgMAogICAgaW50IDB4ODAKCmVycm9yX29wZW5faW5wdXQ6CiAgICBtb3YgZWF4LCA0ICAgICAgICAgICAgICAgICAgICAgOyBzeXNfd3JpdGUKICAgIG1vdiBlYngsIDEgICAgICAgICAgICAgICAgICAgICA7IHN0ZG91dAogICAgbW92IGVjeCwgZXJyb3Jfb3Blbl9pbiAgICAgICAgIDsg0KHQvtC+0LHRidC10L3QuNC1INC+0LEg0L7RiNC40LHQutC1CiAgICBtb3YgZWR4LCBsZW5fZXJyb3Jfb3Blbl9pbiAgICAgOyDQlNC70LjQvdCwINGB0L7QvtCx0YnQtdC90LjRjwogICAgaW50IDB4ODAKICAgIGptcCBleGl0CgplcnJvcl9vcGVuX291dHB1dDoKICAgIG1vdiBlYXgsIDQgICAgICAgICAgICAgICAgICAgICA7IHN5c193cml0ZQogICAgbW92IGVieCwgMSAgICAgICAgICAgICAgICAgICAgIDsgc3Rkb3V0CiAgICBtb3YgZWN4LCBlcnJvcl9vcGVuX291dCAgICAgICAgOyDQodC+0L7QsdGJ0LXQvdC40LUg0L7QsSDQvtGI0LjQsdC60LUKICAgIG1vdiBlZHgsIGxlbl9lcnJvcl9vcGVuX291dCAgICA7INCU0LvQuNC90LAg0YHQvtC+0LHRidC10L3QuNGPCiAgICBpbnQgMHg4MAogICAgam1wIGV4aXQK