131 lines
2.8 KiB
NASM
131 lines
2.8 KiB
NASM
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
|
||
|