global _start

section .data
buff times 256 db 0
buffSize dq $-buff
count dq 0

section .text
default rel

_start:
    lea rsi, [buff]
    lea rdi, [count]
    mov rdx, [buffSize]
    call read_text
    
    mov al, 0xA
    lea rdi, [buff]
    mov rcx, [count]
    repne scasb

    ; Теперь rdi указывает на символ после \n
    ; Вычисляем длину строки: rdi - buff
    lea rax, [buff]
    sub rdi, rax
    mov [count], rdi  ; Сохраняем длину строки в count

    ; rsi уже установлен на buff + длина строки, т.е. на числе
    mov rsi, rax
    add rsi, rdi
    mov rdx, 256
    call read_num

    mov rcx, rax
    jrcxz .return
.while:
    lea rsi, [buff]
    mov rdx, [count]
    call write_text
    loop .while

.return:
    mov rax, 60
    mov rdi, 0
    syscall


; Функция читает текст в буффер
; In:
;   - RSI - указатель на буффер
;   - RDI - указатель на адрес для сохранения длины
;   - RDX - длина буффера
; Регистры не изменяет
read_text:
    push rax
    push rdi


    mov rax, 0          ; sys_read
    mov rdi, 0          ; stdin
    syscall

    pop rdi
    mov [rdi], rax

    pop rax
    ret

; Функция выводит buff
; In:
;   - RSI - начало буфера
;   - RDX - размер буфера
; Регистры не изменяет
write_text:
    push rcx
    push rax
    push rsi
    push rdx

    mov rax, 1          ; sys_write
    mov rdi, 1          ; stdout
    syscall

    pop rdx
    pop rsi
    pop rax
    pop rcx
    ret


; Функция читает число из буфера
; In:
;   - RSI - указатель на буффер
;   - RDX - длина буффера
; Out: 
;   - RAX - число
read_num:
    push rbx
    push rcx
    xor rbx, rbx        ; обнулить регистр для символов
    xor rax, rax        ; обнулить аккумулирующий регистр
    mov rcx, 10         ; множитель для сдвига

    mov rdi, rsi
    add rdi, rdx

    .while:
        cmp rsi, rdi        ; сначала проверяем границы, чтобы не читать за пределами
        jge .return

        mov bl, [rsi]       ; прочитать текущий символ

        cmp bl, 0xA         ; если конец строки (\n) - закончить
        je .return
        cmp bl, 0x0           ; если null (\0) - закончить
        jz .return
        cmp bl, ' '         ; если пробел - закончить
        jz .return

        mul rcx
        and bl, 0x0F
        add rax, rbx
        inc rsi
        jmp .while

.return:
    pop rcx
    pop rbx
    ret

