fork download
  1. section .data
  2. usage db "Usage: ./caesar {input_file} {output_file} {shift}", 10, 0
  3. len_usage equ $ - usage
  4.  
  5. error_open_in db "Error: Cannot open input file.", 10, 0
  6. len_error_open_in equ $ - error_open_in
  7.  
  8. error_open_out db "Error: Cannot open output file.", 10, 0
  9. len_error_open_out equ $ - error_open_out
  10.  
  11. section .bss
  12. bytes_read resd 1
  13. buffer resb 1024
  14. buffer_size equ 1024
  15.  
  16. section .text
  17. global _start
  18.  
  19. _start:
  20. ; В _start стек выглядит так:
  21. ; [esp]: argc
  22. ; [esp+4]: argv[0] (имя программы)
  23. ; [esp+8]: argv[1] (input_file)
  24. ; [esp+12]: argv[2] (output_file)
  25. ; [esp+16]: argv[3] (shift)
  26.  
  27. mov eax, [esp] ; argc
  28. cmp eax, 4 ; Проверяем, что argc == 4
  29. je process_args ; Если да, продолжаем обработку аргументов
  30.  
  31. ; Вывод использования программы
  32. mov eax, 4 ; sys_write
  33. mov ebx, 1 ; stdout
  34. mov ecx, usage ; Адрес строки
  35. mov edx, len_usage ; Длина строки
  36. int 0x80 ; Вызов ядра
  37. jmp exit ; Завершаем программу
  38.  
  39. process_args:
  40. mov ebx, [esp+8] ; argv[1]: input_file
  41. mov ecx, [esp+12] ; argv[2]: output_file
  42. mov edx, [esp+16] ; argv[3]: shift
  43.  
  44. ; Открыть входной файл
  45. mov eax, 5 ; sys_open
  46. mov esi, ebx ; input_file
  47. xor edi, edi ; O_RDONLY
  48. int 0x80
  49. cmp eax, 0 ; Проверка ошибки
  50. jl error_open_input
  51. mov ebx, eax ; Сохраняем дескриптор входного файла
  52.  
  53. ; Открыть выходной файл
  54. mov eax, 5 ; sys_open
  55. mov esi, ecx ; output_file
  56. mov edi, 577 ; O_WRONLY | O_CREAT | O_TRUNC (577 = 0x241)
  57. mov ebp, 0666 ; Права доступа
  58. int 0x80
  59. cmp eax, 0 ; Проверка ошибки
  60. jl error_open_output
  61. mov ecx, eax ; Сохраняем дескриптор выходного файла
  62.  
  63. ; Получить сдвиг
  64. sub edx, '0' ; Преобразуем ASCII в число
  65. and edx, 31 ; Ограничиваем диапазон от 0 до 31
  66.  
  67. read_loop:
  68. ; Чтение из входного файла
  69. mov eax, 3 ; sys_read
  70. mov edi, ebx ; Дескриптор входного файла
  71. mov esi, buffer ; Буфер для чтения
  72. mov edx, buffer_size ; Размер буфера
  73. int 0x80
  74. cmp eax, 0 ; EOF или ошибка
  75. jle close_files
  76. mov dword [bytes_read], eax
  77.  
  78. ; Обработка данных
  79. mov esi, buffer ; Указатель на буфер
  80. mov edi, buffer ; Указатель на запись
  81. mov ecx, dword [bytes_read] ; Количество прочитанных байт
  82. process_char:
  83. lodsb ; Загружаем байт из [esi]
  84. cmp al, 'A'
  85. jb skip_char
  86. cmp al, 'Z'
  87. jbe upper_case
  88. cmp al, 'a'
  89. jb skip_char
  90. cmp al, 'z'
  91. ja skip_char
  92.  
  93. lower_case:
  94. sub al, 'a'
  95. add al, dl ; Применяем сдвиг
  96. xor ah, ah ; Подготовка для модульного деления
  97. mov bl, 26 ; Алфавит латинских строчных букв
  98. div bl ; Делим на 26
  99. add al, 'a'
  100. jmp store_char
  101.  
  102. upper_case:
  103. sub al, 'A'
  104. add al, dl ; Применяем сдвиг
  105. xor ah, ah ; Подготовка для модульного деления
  106. mov bl, 26 ; Алфавит латинских прописных букв
  107. div bl ; Делим на 26
  108. add al, 'A'
  109. jmp store_char
  110.  
  111. skip_char:
  112. jmp next_char
  113.  
  114. store_char:
  115. stosb ; Сохраняем обработанный символ в [edi]
  116.  
  117. next_char:
  118. loop process_char ; Переходим к следующему символу
  119.  
  120. ; Запись данных в выходной файл
  121. mov eax, 4 ; sys_write
  122. mov ebx, ecx ; Дескриптор выходного файла
  123. mov ecx, buffer ; Буфер для записи
  124. mov edx, dword [bytes_read] ; Количество байт для записи
  125. int 0x80
  126. jmp read_loop
  127.  
  128. close_files:
  129. ; Закрытие файлов
  130. mov eax, 6 ; sys_close
  131. mov ebx, ebx ; Закрыть входной файл
  132. int 0x80
  133.  
  134. mov eax, 6 ; sys_close
  135. mov ebx, ecx ; Закрыть выходной файл
  136. int 0x80
  137.  
  138. exit:
  139. mov eax, 1 ; sys_exit
  140. xor ebx, ebx ; Код выхода 0
  141. int 0x80
  142.  
  143. error_open_input:
  144. mov eax, 4 ; sys_write
  145. mov ebx, 1 ; stdout
  146. mov ecx, error_open_in ; Сообщение об ошибке
  147. mov edx, len_error_open_in ; Длина сообщения
  148. int 0x80
  149. jmp exit
  150.  
  151. error_open_output:
  152. mov eax, 4 ; sys_write
  153. mov ebx, 1 ; stdout
  154. mov ecx, error_open_out ; Сообщение об ошибке
  155. mov edx, len_error_open_out ; Длина сообщения
  156. int 0x80
  157. jmp exit
  158.  
Success #stdin #stdout 0s 5276KB
stdin
Standard input is empty
stdout
Usage: ./caesar {input_file} {output_file} {shift}