repeat_str

This commit is contained in:
Пытков Роман
2025-09-23 14:26:36 +03:00
parent 01c7a248ad
commit 00273bf803
5 changed files with 216 additions and 1 deletions

BIN
docs/Intel manual.pdf Normal file

Binary file not shown.

View File

@@ -9,9 +9,12 @@
{ {
"path": "even_odd" "path": "even_odd"
}, },
{
"path": "repeat_str"
},
{ {
"path": "docs" "path": "docs"
} },
], ],
"settings": { "settings": {
"debug.allowBreakpointsEverywhere": true, "debug.allowBreakpointsEverywhere": true,

29
repeat_str/.vscode/launch.json vendored Normal file
View File

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

53
repeat_str/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,53 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "asm64",
"type": "shell",
"command": [
"builddir=${workspaceFolder}/build;",
"mkdir -p $builddir;",
"rawfilename=$builddir/repeat_str;",
"nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/repeat_str.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/repeat_str;",
"nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/repeat_str.asm;",
"gcc -o $rawfilename $rawfilename.o;"
],
"problemMatcher": {
"pattern": {
"regexp": "error"
}
},
"presentation": {
"focus": true,
"panel": "dedicated",
"reveal": "silent",
"clear": true
},
}
]
}

130
repeat_str/repeat_str.asm Normal file
View File

@@ -0,0 +1,130 @@
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