fork download
  1. section .data
  2. error_no_arg db "Error: File not specified.", 10, 0
  3. error_open db "Error: Could not open file.", 10, 0
  4. error_open_code db "Open failed with error code: ", 0
  5. error_read db "Error: Failed to read file.", 10, 0
  6. newline db 10
  7.  
  8. section .bss
  9. buffer resb 1024
  10. error_code resb 4
  11.  
  12. section .text
  13. global _start
  14.  
  15. _start:
  16. ; Проверка наличия аргументов командной строки
  17. mov eax, [esp + 4] ; argc
  18. cmp eax, 2 ; argc должно быть >= 2
  19. jae open_file ; Если да, перейти к открытию файла
  20.  
  21. ; Вывод ошибки: файл не указан
  22. mov eax, 4 ; sys_write
  23. mov ebx, 1 ; stdout
  24. mov ecx, error_no_arg ; сообщение об ошибке
  25. mov edx, 26 ; длина сообщения
  26. int 0x80
  27. jmp exit_program
  28.  
  29. open_file:
  30. ; Отладка: выводим имя файла (argv[1])
  31. lea ebx, [esp + 8] ; Загрузка адреса argv[1]
  32. mov eax, 4 ; sys_write
  33. mov ecx, ebx ; Указатель на имя файла
  34. mov edx, 100 ; Ограничение на длину строки
  35. int 0x80
  36.  
  37. ; Попытка открыть файл
  38. mov eax, 5 ; sys_open
  39. lea ebx, [esp + 8] ; Загрузка адреса argv[1]
  40. mov ecx, 0 ; O_RDONLY
  41. int 0x80
  42.  
  43. ; Проверка, был ли файл открыт успешно
  44. cmp eax, 0 ; Проверка, что eax содержит файловый дескриптор >= 0
  45. jl file_open_error ; Если ошибка, перейти к обработке
  46.  
  47. ; Сохраняем файловый дескриптор в ebx
  48. mov ebx, eax
  49.  
  50. ; Выводим информацию о том, что файл успешно открыт
  51. mov eax, 4 ; sys_write
  52. mov ebx, 1 ; stdout
  53. lea ecx, [esp + 8] ; Указатель на имя файла
  54. mov edx, 100 ; Ограничение на длину строки
  55. int 0x80
  56.  
  57. read_file:
  58. mov eax, 3 ; sys_read
  59. mov ecx, buffer ; Указатель на буфер
  60. mov edx, 1024 ; Количество байт для чтения
  61. int 0x80
  62. cmp eax, 0 ; Проверка: достигнут конец файла?
  63. jle file_read_error ; Если ошибка, перейти к обработке
  64.  
  65. ; Поиск второй строки
  66. mov esi, buffer ; esi указывает на начало буфера
  67. xor ecx, ecx ; Счетчик строк
  68.  
  69. find_second_line:
  70. mov al, byte [esi] ; Читаем символ из буфера
  71. cmp al, 0 ; Если достигнут конец данных, выходим
  72. je end_of_buffer
  73. cmp al, [newline] ; Проверяем символ новой строки
  74. jne skip_char
  75.  
  76. inc ecx ; Увеличиваем счетчик строк
  77. cmp ecx, 2 ; Достигли второй строки?
  78. je print_second_line
  79.  
  80. skip_char:
  81. inc esi ; Следующий символ
  82. jmp find_second_line
  83.  
  84. print_second_line:
  85. ; Печатаем вторую строку
  86. mov edx, 0 ; Считаем длину второй строки
  87. find_line_end:
  88. mov al, byte [esi + edx]
  89. cmp al, 0 ; Конец данных?
  90. je do_write
  91. cmp al, [newline] ; Конец строки?
  92. je do_write
  93. inc edx ; Увеличиваем длину строки
  94. jmp find_line_end
  95.  
  96. do_write:
  97. mov eax, 4 ; sys_write
  98. mov ebx, 1 ; stdout
  99. lea ecx, [esi] ; Указатель на начало второй строки
  100. int 0x80
  101. jmp close_file
  102.  
  103. end_of_buffer:
  104. close_file:
  105. ; Закрытие файла
  106. mov eax, 6 ; sys_close
  107. mov ebx, [esp + 4] ; Дескриптор файла, сохраняем в ebx
  108. int 0x80
  109. jmp exit_program
  110.  
  111. file_open_error:
  112. ; Вывод ошибки: не удалось открыть файл
  113. mov eax, 4 ; sys_write
  114. mov ebx, 1 ; stdout
  115. mov ecx, error_open ; сообщение об ошибке
  116. mov edx, 30 ; длина сообщения
  117. int 0x80
  118.  
  119. ; Печатаем код ошибки
  120. mov eax, 5 ; sys_open возвращает код ошибки в eax
  121. lea ebx, [error_code] ; Указатель на переменную для хранения кода ошибки
  122. mov [error_code], eax ; Сохраняем код ошибки в переменной
  123. mov eax, [error_code] ; Загружаем код ошибки
  124. ; Преобразуем код ошибки в строку и выводим
  125. call print_error_code
  126.  
  127. jmp exit_program
  128.  
  129. file_read_error:
  130. ; Вывод ошибки: не удалось прочитать файл
  131. mov eax, 4 ; sys_write
  132. mov ebx, 1 ; stdout
  133. mov ecx, error_read ; сообщение об ошибке
  134. mov edx, 29 ; длина сообщения
  135. int 0x80
  136.  
  137. exit_program:
  138. ; Завершаем программу
  139. mov eax, 1 ; sys_exit
  140. xor ebx, ebx ; Код завершения: 0
  141. int 0x80
  142.  
  143. print_error_code:
  144. ; Печатает код ошибки в виде строки
  145. ; Ожидается, что eax содержит код ошибки
  146. add eax, '0' ; Преобразуем код ошибки в символ
  147. mov [error_code], al ; Записываем символ в буфер
  148. mov eax, 4 ; sys_write
  149. mov ebx, 1 ; stdout
  150. lea ecx, [error_code] ; Указатель на буфер с кодом ошибки
  151. mov edx, 1 ; Размер выводимого символа
  152. int 0x80
  153. ret
  154.  
Success #stdin #stdout 0s 5276KB
stdin
Standard input is empty
stdout
Error: Could not open file.
O5