diff --git a/stepik_base/less_greater_10_neg/.vscode/launch.json b/stepik_base/less_greater_10_neg/.vscode/launch.json new file mode 100644 index 0000000..200ea85 --- /dev/null +++ b/stepik_base/less_greater_10_neg/.vscode/launch.json @@ -0,0 +1,29 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "(lldb) Launch x64", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/build/less_greater_10_neg", + "cwd": "${workspaceFolder}/build", + "preLaunchTask": "asm64", + }, + { + "name": "(gdb) Launch x64", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/less_greater_10_neg", + "cwd": "${workspaceFolder}/build", + "preLaunchTask": "asm64" + }, + { + "name": "(gdb+gcc) Launch x64", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/less_greater_10_neg", + "cwd": "${workspaceFolder}/build", + "preLaunchTask": "asm64+gcc" + } + ] +} \ No newline at end of file diff --git a/stepik_base/less_greater_10_neg/.vscode/tasks.json b/stepik_base/less_greater_10_neg/.vscode/tasks.json new file mode 100644 index 0000000..db338e9 --- /dev/null +++ b/stepik_base/less_greater_10_neg/.vscode/tasks.json @@ -0,0 +1,53 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "asm64", + "type": "shell", + "command": [ + "builddir=${workspaceFolder}/build;", + "mkdir -p $builddir;", + "rawfilename=$builddir/less_greater_10_neg;", + "nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/less_greater_10_neg.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/less_greater_10_neg;", + "nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/less_greater_10_neg.asm;", + "gcc -o $rawfilename $rawfilename.o;" + ], + "problemMatcher": { + "pattern": { + "regexp": "error" + } + }, + "presentation": { + "focus": true, + "panel": "dedicated", + "reveal": "silent", + "clear": true + }, + } + ] +} \ No newline at end of file diff --git a/stepik_base/less_greater_10_neg/less_greater_10_neg.asm b/stepik_base/less_greater_10_neg/less_greater_10_neg.asm new file mode 100644 index 0000000..b048cec --- /dev/null +++ b/stepik_base/less_greater_10_neg/less_greater_10_neg.asm @@ -0,0 +1,119 @@ +; Макрос для вывода сообщения +; In: +; - %1 - указатель на буффер с сообщением +; - %2 - длина сообщения +%macro PRINT_MSG 2 + mov rsi, %1 + mov rdx, %2 + mov rdi, 1 ; stdout + + mov rax, 1 ; sys_write + syscall +%endmacro + +global _start + +section .data +g_buff times 32 db 0 +g_buff_end: +g_len dq 0 + +g_less_or_equal db "B" +g_less_or_equal_len dq $-g_less_or_equal +g_greater db "A" +g_greater_len dq $-g_greater + +section .text +default rel + +_start: + call read_text + + lea rsi, [rel g_buff] ; поставить указатель на начало буфера + call read_num + + cmp rax, 10 + jle .le +.g: + lea rdi, [g_greater] + mov rdx, [g_greater_len] + jmp .print +.le: + lea rdi, [g_less_or_equal] + mov rdx, [g_less_or_equal_len] + +.print: + PRINT_MSG rdi, rdx + + 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 g_buff] ; адрес буфера + mov rdx, 256 ; количество байт + syscall + mov [g_len], rax + + pop rdx + pop rsi + pop rdi + pop rax + ret + + +; Функция читает число из stdin +; Out: RAX +read_num: + push rbx + push rcx + + xor r8, 1 ; r8 - флаг знака + xor rbx, rbx ; обнулить регистр для символов + xor rax, rax ; обнулить аккумулирующий регистр + mov rcx, 10 ; множитель для сдвига + + lea rdi, [g_buff] ; rdi - конец данных + add rdi, [g_len] + + .while: + cmp rsi, rdi ; сначала проверяем границы, чтобы не читать за пределами + jge .return + + mov bl, [rsi] ; прочитать текущий символ + + cmp bl, 0xA ; если конец строки (\n) - закончить + je .return + cmp bl, 0 ; если null (\0) - закончить + jz .return + cmp bl, ' ' ; если пробел - закончить + jz .return + + cmp bl, '-' + jne .add + .neg: + neg r8 + jmp .continue + .add: + mul rcx + and bl, 0x0F + add rax, rbx + + .continue: + inc rsi + jmp .while + +.return: + mul r8 + pop rcx + pop rbx + ret diff --git a/stepik_base/nasm.code-workspace b/stepik_base/nasm.code-workspace index 1d78126..8966e78 100644 --- a/stepik_base/nasm.code-workspace +++ b/stepik_base/nasm.code-workspace @@ -21,6 +21,9 @@ { "path": "less_greater_10" }, + { + "path": "less_greater_10_neg" + }, { "path": "../docs" },