Подсчёт слов

This commit is contained in:
Пытков Роман
2025-09-23 21:12:41 +03:00
parent 4e111c6148
commit 0716753b1f
4 changed files with 214 additions and 0 deletions

View File

@@ -27,6 +27,9 @@
{ {
"path": "10_to_2" "path": "10_to_2"
}, },
{
"path": "word_count"
},
{ {
"path": "../docs" "path": "../docs"
}, },

View File

@@ -0,0 +1,29 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Launch x64",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/build/word_count",
"cwd": "${workspaceFolder}/build",
"preLaunchTask": "asm64",
},
{
"name": "(gdb) Launch x64",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/word_count",
"cwd": "${workspaceFolder}/build",
"preLaunchTask": "asm64"
},
{
"name": "(gdb+gcc) Launch x64",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/word_count",
"cwd": "${workspaceFolder}/build",
"preLaunchTask": "asm64+gcc"
}
]
}

View File

@@ -0,0 +1,53 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "asm64",
"type": "shell",
"command": [
"builddir=${workspaceFolder}/build;",
"mkdir -p $builddir;",
"rawfilename=$builddir/word_count;",
"nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/word_count.asm;",
"ld -g -o $rawfilename $rawfilename.o;"
],
"problemMatcher": {
"pattern": {
"regexp": "error"
}
},
"presentation": {
"focus": true,
"panel": "dedicated",
"reveal": "silent",
"clear": true
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "asm64+gcc",
"type": "shell",
"command": [
"builddir=${workspaceFolder}/build;",
"mkdir -p $builddir;",
"rawfilename=$builddir/word_count;",
"nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/word_count.asm;",
"gcc -o $rawfilename $rawfilename.o;"
],
"problemMatcher": {
"pattern": {
"regexp": "error"
}
},
"presentation": {
"focus": true,
"panel": "dedicated",
"reveal": "silent",
"clear": true
},
}
]
}

View File

@@ -0,0 +1,129 @@
global _start
section .data
buff times 350 db 0
buffend:
count dq 0
section .text
default rel
_start:
call read_text
xor rax, rax
mov rcx, [count]
dec rcx
lea rsi, [buff]
mov r10, 1 ; просто единица
mov r8, 0 ; прошлый символ - не пробел
.loop:
mov dl, [rsi]
cmp dl, ' '
jne .continue ; если сейчас не пробел - выйти
test r8, r8
jz .continue ; если прошлое пробел - выйти
.space_after_word:
inc rax
.continue:
mov r8, 0
cmp dl, ' '
cmovne r8, r10
inc rsi
loop .loop
test r8, r8
jz .print ; если прошлое пробел - выйти
inc rax
.print:
call print_num_to_buf
mov rdx, [count]
call write_text
mov rax, 60
mov rdi, 0
syscall
; Функция читает текст в буффер
; Регистры не изменяет
read_text:
push rax
push rdi
push rsi
push rdx
mov rax, 0 ; sys_read
mov rdi, 0 ; stdin
lea rsi, [rel buff] ; адрес буфера
mov rdx, 256 ; количество байт
syscall
mov [count], rax
pop rdx
pop rsi
pop rdi
pop rax
ret
; Функция выводит buff
; In:
; - RSI - начало буфера
; - RDX - размер буфера
; Регистры не изменяет
write_text:
push rax
push rdi
push rsi
push rdx
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
syscall
mov [count], rax
pop rdx
pop rsi
pop rdi
pop rax
ret
; Функция выводит число в buff
; In: RAX
; Out: RSI - указатель на начало строки
print_num_to_buf:
lea rsi, [buffend]
dec rsi
mov rdi, rsi ; сохранить последний адрес
mov byte [rsi], 0 ; вписать нуль
dec rsi
mov byte [rsi], 0xA ; вписать перенос строки
dec rsi
mov byte [rsi], '0'
test rax, rax
jz .return
mov rcx, 10 ; десятичный делитель
.while:
xor rdx, rdx
test rax, rax
jz .break
div rcx
or dl, 0x30
mov [rsi], dl
dec rsi
jmp .while
.break:
inc rsi
.return:
sub rdi, rsi
inc rdi
mov [count], rdi
ret