section .data
usage db "Usage: ./caesar {input_file} {output_file} {shift}", 10, 0
len_usage equ $ - usage
error_open_in db "Error: Cannot open input file.", 10, 0
len_error_open_in equ $ - error_open_in
error_open_out db "Error: Cannot open output file.", 10, 0
len_error_open_out equ $ - error_open_out
section .bss
bytes_read resd 1
buffer resb 1024
buffer_size equ 1024
section .text
global _start
_start:
; Проверка количества аргументов
mov eax, [esp] ; 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, [esp+4] ; argv[1] (input_file)
mov ecx, [esp+8] ; argv[2] (output_file)
mov edx, [esp+12] ; argv[3] (shift)
; Открыть входной файл
mov eax, 5 ; sys_open
mov esi, ebx ; input_file
xor edi, edi ; O_RDONLY
int 0x80
cmp eax, 0 ; Проверка ошибки
jl error_open_input
mov ebx, eax ; Дескриптор входного файла
; Открыть выходной файл
mov eax, 5 ; sys_open
mov esi, ecx ; output_file
mov edi, 577 ; O_WRONLY | O_CREAT | O_TRUNC (0666)
mov ebp, 0666 ; Права доступа
int 0x80
cmp eax, 0 ; Проверка ошибки
jl error_open_output
mov ecx, eax ; Дескриптор выходного файла
; Получить сдвиг
sub edx, '0' ; Преобразуем ASCII в число
and edx, 31 ; Ограничение на диапазон от 0 до 31
read_loop:
; Чтение из входного файла
mov eax, 3 ; sys_read
mov edi, ebx ; Дескриптор входного файла
mov esi, buffer ; Буфер для чтения
mov edx, buffer_size ; Размер буфера
int 0x80
cmp eax, 0 ; EOF или ошибка
jle close_files
mov dword [bytes_read], eax
; Обработка данных
mov esi, buffer ; Указатель на буфер
mov edi, buffer ; Указатель на запись
mov ecx, dword [bytes_read] ; Количество прочитанных байт
process_char:
lodsb ; Загружаем байт из [esi]
cmp al, 'A'
jb skip_char
cmp al, 'Z'
jbe upper_case
cmp al, 'a'
jb skip_char
cmp al, 'z'
ja skip_char
lower_case:
sub al, 'a'
add al, dl ; Применяем сдвиг
xor ah, ah ; Подготовка для модульного деления
mov bl, 26 ; Алфавит латинских строчных букв
div bl ; Делим на 26
add al, 'a'
jmp store_char
upper_case:
sub al, 'A'
add al, dl ; Применяем сдвиг
xor ah, ah ; Подготовка для модульного деления
mov bl, 26 ; Алфавит латинских прописных букв
div bl ; Делим на 26
add al, 'A'
jmp store_char
skip_char:
jmp next_char
store_char:
stosb ; Сохраняем обработанный символ в [edi]
next_char:
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
c2VjdGlvbiAuZGF0YQogICAgdXNhZ2UgZGIgIlVzYWdlOiAuL2NhZXNhciB7aW5wdXRfZmlsZX0ge291dHB1dF9maWxlfSB7c2hpZnR9IiwgMTAsIDAKICAgIGxlbl91c2FnZSBlcXUgJCAtIHVzYWdlCgogICAgZXJyb3Jfb3Blbl9pbiBkYiAiRXJyb3I6IENhbm5vdCBvcGVuIGlucHV0IGZpbGUuIiwgMTAsIDAKICAgIGxlbl9lcnJvcl9vcGVuX2luIGVxdSAkIC0gZXJyb3Jfb3Blbl9pbgoKICAgIGVycm9yX29wZW5fb3V0IGRiICJFcnJvcjogQ2Fubm90IG9wZW4gb3V0cHV0IGZpbGUuIiwgMTAsIDAKICAgIGxlbl9lcnJvcl9vcGVuX291dCBlcXUgJCAtIGVycm9yX29wZW5fb3V0CgpzZWN0aW9uIC5ic3MKICAgIGJ5dGVzX3JlYWQgcmVzZCAxCiAgICBidWZmZXIgcmVzYiAxMDI0CiAgICBidWZmZXJfc2l6ZSBlcXUgMTAyNAoKc2VjdGlvbiAudGV4dAogICAgZ2xvYmFsIF9zdGFydAoKX3N0YXJ0OgogICAgOyDQn9GA0L7QstC10YDQutCwINC60L7Qu9C40YfQtdGB0YLQstCwINCw0YDQs9GD0LzQtdC90YLQvtCyCiAgICBtb3YgZWF4LCBbZXNwXSAgICAgICAgICAgICAgOyBhcmdjCiAgICBjbXAgZWF4LCA0ICAgICAgICAgICAgICAgICAgOyBhcmdjINC00L7Qu9C20L3QviDQsdGL0YLRjCA0CiAgICBqZSBwcm9jZXNzX2FyZ3MKCiAgICA7INCS0YvQstC+0LQg0LjRgdC/0L7Qu9GM0LfQvtCy0LDQvdC40Y8g0L/RgNC+0LPRgNCw0LzQvNGLCiAgICBtb3YgZWF4LCA0ICAgICAgICAgICAgICAgICAgOyBzeXNfd3JpdGUKICAgIG1vdiBlYngsIDEgICAgICAgICAgICAgICAgICA7IHN0ZG91dAogICAgbW92IGVjeCwgdXNhZ2UgICAgICAgICAgICAgIDsg0JDQtNGA0LXRgSDRgdGC0YDQvtC60LgKICAgIG1vdiBlZHgsIGxlbl91c2FnZSAgICAgICAgICA7INCU0LvQuNC90LAg0YHRgtGA0L7QutC4CiAgICBpbnQgMHg4MCAgICAgICAgICAgICAgICAgICAgOyDQktGL0LfQvtCyINGP0LTRgNCwCiAgICBqbXAgZXhpdAoKcHJvY2Vzc19hcmdzOgogICAgOyDQn9C+0LvRg9GH0LXQvdC40LUg0L/QsNGA0LDQvNC10YLRgNC+0LIKICAgIG1vdiBlYngsIFtlc3ArNF0gICAgICAgICAgICA7IGFyZ3ZbMV0gKGlucHV0X2ZpbGUpCiAgICBtb3YgZWN4LCBbZXNwKzhdICAgICAgICAgICAgOyBhcmd2WzJdIChvdXRwdXRfZmlsZSkKICAgIG1vdiBlZHgsIFtlc3ArMTJdICAgICAgICAgICA7IGFyZ3ZbM10gKHNoaWZ0KQoKICAgIDsg0J7RgtC60YDRi9GC0Ywg0LLRhdC+0LTQvdC+0Lkg0YTQsNC50LsKICAgIG1vdiBlYXgsIDUgICAgICAgICAgICAgICAgICA7IHN5c19vcGVuCiAgICBtb3YgZXNpLCBlYnggICAgICAgICAgICAgICAgOyBpbnB1dF9maWxlCiAgICB4b3IgZWRpLCBlZGkgICAgICAgICAgICAgICAgOyBPX1JET05MWQogICAgaW50IDB4ODAKICAgIGNtcCBlYXgsIDAgICAgICAgICAgICAgICAgICA7INCf0YDQvtCy0LXRgNC60LAg0L7RiNC40LHQutC4CiAgICBqbCBlcnJvcl9vcGVuX2lucHV0CiAgICBtb3YgZWJ4LCBlYXggICAgICAgICAgICAgICAgOyDQlNC10YHQutGA0LjQv9GC0L7RgCDQstGF0L7QtNC90L7Qs9C+INGE0LDQudC70LAKCiAgICA7INCe0YLQutGA0YvRgtGMINCy0YvRhdC+0LTQvdC+0Lkg0YTQsNC50LsKICAgIG1vdiBlYXgsIDUgICAgICAgICAgICAgICAgICA7IHN5c19vcGVuCiAgICBtb3YgZXNpLCBlY3ggICAgICAgICAgICAgICAgOyBvdXRwdXRfZmlsZQogICAgbW92IGVkaSwgNTc3ICAgICAgICAgICAgICAgIDsgT19XUk9OTFkgfCBPX0NSRUFUIHwgT19UUlVOQyAoMDY2NikKICAgIG1vdiBlYnAsIDA2NjYgICAgICAgICAgICAgICA7INCf0YDQsNCy0LAg0LTQvtGB0YLRg9C/0LAKICAgIGludCAweDgwCiAgICBjbXAgZWF4LCAwICAgICAgICAgICAgICAgICAgOyDQn9GA0L7QstC10YDQutCwINC+0YjQuNCx0LrQuAogICAgamwgZXJyb3Jfb3Blbl9vdXRwdXQKICAgIG1vdiBlY3gsIGVheCAgICAgICAgICAgICAgICA7INCU0LXRgdC60YDQuNC/0YLQvtGAINCy0YvRhdC+0LTQvdC+0LPQviDRhNCw0LnQu9CwCgogICAgOyDQn9C+0LvRg9GH0LjRgtGMINGB0LTQstC40LMKICAgIHN1YiBlZHgsICcwJyAgICAgICAgICAgICAgICA7INCf0YDQtdC+0LHRgNCw0LfRg9C10LwgQVNDSUkg0LIg0YfQuNGB0LvQvgogICAgYW5kIGVkeCwgMzEgICAgICAgICAgICAgICAgIDsg0J7Qs9GA0LDQvdC40YfQtdC90LjQtSDQvdCwINC00LjQsNC/0LDQt9C+0L0g0L7RgiAwINC00L4gMzEKCnJlYWRfbG9vcDoKICAgIDsg0KfRgtC10L3QuNC1INC40Lcg0LLRhdC+0LTQvdC+0LPQviDRhNCw0LnQu9CwCiAgICBtb3YgZWF4LCAzICAgICAgICAgICAgICAgICAgOyBzeXNfcmVhZAogICAgbW92IGVkaSwgZWJ4ICAgICAgICAgICAgICAgIDsg0JTQtdGB0LrRgNC40L/RgtC+0YAg0LLRhdC+0LTQvdC+0LPQviDRhNCw0LnQu9CwCiAgICBtb3YgZXNpLCBidWZmZXIgICAgICAgICAgICAgOyDQkdGD0YTQtdGAINC00LvRjyDRh9GC0LXQvdC40Y8KICAgIG1vdiBlZHgsIGJ1ZmZlcl9zaXplICAgICAgICA7INCg0LDQt9C80LXRgCDQsdGD0YTQtdGA0LAKICAgIGludCAweDgwCiAgICBjbXAgZWF4LCAwICAgICAgICAgICAgICAgICAgOyBFT0Yg0LjQu9C4INC+0YjQuNCx0LrQsAogICAgamxlIGNsb3NlX2ZpbGVzCiAgICBtb3YgZHdvcmQgW2J5dGVzX3JlYWRdLCBlYXgKCiAgICA7INCe0LHRgNCw0LHQvtGC0LrQsCDQtNCw0L3QvdGL0YUKICAgIG1vdiBlc2ksIGJ1ZmZlciAgICAgICAgICAgICA7INCj0LrQsNC30LDRgtC10LvRjCDQvdCwINCx0YPRhNC10YAKICAgIG1vdiBlZGksIGJ1ZmZlciAgICAgICAgICAgICA7INCj0LrQsNC30LDRgtC10LvRjCDQvdCwINC30LDQv9C40YHRjAogICAgbW92IGVjeCwgZHdvcmQgW2J5dGVzX3JlYWRdIDsg0JrQvtC70LjRh9C10YHRgtCy0L4g0L/RgNC+0YfQuNGC0LDQvdC90YvRhSDQsdCw0LnRggpwcm9jZXNzX2NoYXI6CiAgICBsb2RzYiAgICAgICAgICAgICAgICAgICAgICAgOyDQl9Cw0LPRgNGD0LbQsNC10Lwg0LHQsNC50YIg0LjQtyBbZXNpXQogICAgY21wIGFsLCAnQScKICAgIGpiIHNraXBfY2hhcgogICAgY21wIGFsLCAnWicKICAgIGpiZSB1cHBlcl9jYXNlCiAgICBjbXAgYWwsICdhJwogICAgamIgc2tpcF9jaGFyCiAgICBjbXAgYWwsICd6JwogICAgamEgc2tpcF9jaGFyCgpsb3dlcl9jYXNlOgogICAgc3ViIGFsLCAnYScKICAgIGFkZCBhbCwgZGwgICAgICAgICAgICAgICAgIDsg0J/RgNC40LzQtdC90Y/QtdC8INGB0LTQstC40LMKICAgIHhvciBhaCwgYWggICAgICAgICAgICAgICAgIDsg0J/QvtC00LPQvtGC0L7QstC60LAg0LTQu9GPINC80L7QtNGD0LvRjNC90L7Qs9C+INC00LXQu9C10L3QuNGPCiAgICBtb3YgYmwsIDI2ICAgICAgICAgICAgICAgICA7INCQ0LvRhNCw0LLQuNGCINC70LDRgtC40L3RgdC60LjRhSDRgdGC0YDQvtGH0L3Ri9GFINCx0YPQutCyCiAgICBkaXYgYmwgICAgICAgICAgICAgICAgICAgICA7INCU0LXQu9C40Lwg0L3QsCAyNgogICAgYWRkIGFsLCAnYScKICAgIGptcCBzdG9yZV9jaGFyCgp1cHBlcl9jYXNlOgogICAgc3ViIGFsLCAnQScKICAgIGFkZCBhbCwgZGwgICAgICAgICAgICAgICAgIDsg0J/RgNC40LzQtdC90Y/QtdC8INGB0LTQstC40LMKICAgIHhvciBhaCwgYWggICAgICAgICAgICAgICAgIDsg0J/QvtC00LPQvtGC0L7QstC60LAg0LTQu9GPINC80L7QtNGD0LvRjNC90L7Qs9C+INC00LXQu9C10L3QuNGPCiAgICBtb3YgYmwsIDI2ICAgICAgICAgICAgICAgICA7INCQ0LvRhNCw0LLQuNGCINC70LDRgtC40L3RgdC60LjRhSDQv9GA0L7Qv9C40YHQvdGL0YUg0LHRg9C60LIKICAgIGRpdiBibCAgICAgICAgICAgICAgICAgICAgIDsg0JTQtdC70LjQvCDQvdCwIDI2CiAgICBhZGQgYWwsICdBJwogICAgam1wIHN0b3JlX2NoYXIKCnNraXBfY2hhcjoKICAgIGptcCBuZXh0X2NoYXIKCnN0b3JlX2NoYXI6CiAgICBzdG9zYiAgICAgICAgICAgICAgICAgICAgICA7INCh0L7RhdGA0LDQvdGP0LXQvCDQvtCx0YDQsNCx0L7RgtCw0L3QvdGL0Lkg0YHQuNC80LLQvtC7INCyIFtlZGldCgpuZXh0X2NoYXI6CiAgICBsb29wIHByb2Nlc3NfY2hhciAgICAgICAgICA7INCf0LXRgNC10YXQvtC00LjQvCDQuiDRgdC70LXQtNGD0Y7RidC10LzRgyDRgdC40LzQstC+0LvRgwoKICAgIDsg0JfQsNC/0LjRgdGMINC00LDQvdC90YvRhSDQsiDQstGL0YXQvtC00L3QvtC5INGE0LDQudC7CiAgICBtb3YgZWF4LCA0ICAgICAgICAgICAgICAgICAgOyBzeXNfd3JpdGUKICAgIG1vdiBlYngsIGVjeCAgICAgICAgICAgICAgICA7INCU0LXRgdC60YDQuNC/0YLQvtGAINCy0YvRhdC+0LTQvdC+0LPQviDRhNCw0LnQu9CwCiAgICBtb3YgZWN4LCBidWZmZXIgICAgICAgICAgICAgOyDQkdGD0YTQtdGAINC00LvRjyDQt9Cw0L/QuNGB0LgKICAgIG1vdiBlZHgsIGR3b3JkIFtieXRlc19yZWFkXSA7INCa0L7Qu9C40YfQtdGB0YLQstC+INCx0LDQudGCINC00LvRjyDQt9Cw0L/QuNGB0LgKICAgIGludCAweDgwCiAgICBqbXAgcmVhZF9sb29wCgpjbG9zZV9maWxlczoKICAgIDsg0JfQsNC60YDRi9GC0LjQtSDRhNCw0LnQu9C+0LIKICAgIG1vdiBlYXgsIDYgICAgICAgICAgICAgICAgICA7IHN5c19jbG9zZQogICAgbW92IGVieCwgZWJ4ICAgICAgICAgICAgICAgIDsg0JfQsNC60YDRi9GC0Ywg0LLRhdC+0LTQvdC+0Lkg0YTQsNC50LsKICAgIGludCAweDgwCgogICAgbW92IGVheCwgNiAgICAgICAgICAgICAgICAgIDsgc3lzX2Nsb3NlCiAgICBtb3YgZWJ4LCBlY3ggICAgICAgICAgICAgICAgOyDQl9Cw0LrRgNGL0YLRjCDQstGL0YXQvtC00L3QvtC5INGE0LDQudC7CiAgICBpbnQgMHg4MAoKZXhpdDoKICAgIG1vdiBlYXgsIDEgICAgICAgICAgICAgICAgICA7IHN5c19leGl0CiAgICB4b3IgZWJ4LCBlYnggICAgICAgICAgICAgICAgOyDQmtC+0LQg0LLRi9GF0L7QtNCwIDAKICAgIGludCAweDgwCgplcnJvcl9vcGVuX2lucHV0OgogICAgbW92IGVheCwgNCAgICAgICAgICAgICAgICAgIDsgc3lzX3dyaXRlCiAgICBtb3YgZWJ4LCAxICAgICAgICAgICAgICAgICAgOyBzdGRvdXQKICAgIG1vdiBlY3gsIGVycm9yX29wZW5faW4gICAgICA7INCh0L7QvtCx0YnQtdC90LjQtSDQvtCxINC+0YjQuNCx0LrQtQogICAgbW92IGVkeCwgbGVuX2Vycm9yX29wZW5faW4gIDsg0JTQu9C40L3QsCDRgdC+0L7QsdGJ0LXQvdC40Y8KICAgIGludCAweDgwCiAgICBqbXAgZXhpdAoKZXJyb3Jfb3Blbl9vdXRwdXQ6CiAgICBtb3YgZWF4LCA0ICAgICAgICAgICAgICAgICAgOyBzeXNfd3JpdGUKICAgIG1vdiBlYngsIDEgICAgICAgICAgICAgICAgICA7IHN0ZG91dAogICAgbW92IGVjeCwgZXJyb3Jfb3Blbl9vdXQgICAgIDsg0KHQvtC+0LHRidC10L3QuNC1INC+0LEg0L7RiNC40LHQutC1CiAgICBtb3YgZWR4LCBsZW5fZXJyb3Jfb3Blbl9vdXQgOyDQlNC70LjQvdCwINGB0L7QvtCx0YnQtdC90LjRjwogICAgaW50IDB4ODAKICAgIGptcCBleGl0Cg==