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