; ===========================================================================
;  ОДНА ЗАДАЧА НА ЧЕТЫРЁХ ЯЗЫКАХ — 1/4: язык ассемблера (x86-64, NASM)
;  Задача: скопировать строку в буфер размером ровно 16 байт.
;
;  ФАЙЛ ПРЕДНАЗНАЧЕН ДЛЯ ЧТЕНИЯ, а не для сборки на занятии.
;  Если хотите увидеть, во что компилятор превращает код на C/C++/Rust,
;  откройте godbolt.org (Compiler Explorer) — это тот же ассемблер,
;  только сгенерированный.
; ===========================================================================

section .bss
    buffer  resb 16         ; буфер: ровно 16 байт, ни байтом больше
    next    resb 8          ; то, что лежит в памяти сразу за буфером
                            ; (в реальной программе здесь может оказаться
                            ;  что угодно: другая переменная, адрес возврата,
                            ;  указатель на функцию)

section .text
global copy_name

; ---------------------------------------------------------------------------
; Вход:  rsi — адрес исходной строки, оканчивающейся нулевым байтом
; Выход: строка скопирована в buffer
; ---------------------------------------------------------------------------
copy_name:
    lea     rdi, [rel buffer]   ; rdi = адрес приёмника
.loop:
    mov     al, [rsi]           ; взять очередной байт источника
    mov     [rdi], al           ; положить его в приёмник
    inc     rsi                 ; сдвинуть указатель источника
    inc     rdi                 ; сдвинуть указатель приёмника
    test    al, al              ; это был нулевой байт (конец строки)?
    jnz     .loop               ; нет — копируем дальше
    ret

; ===========================================================================
;  ЧТО ЗДЕСЬ ВАЖНО УВИДЕТЬ
;
;  Нигде в этом коде не проверяется, поместилась ли строка в 16 байт.
;  Цикл копирует ровно до нулевого байта — сколько бы их ни было.
;  Подадим строку в 40 байт: 24 лишних байта лягут в `next` и дальше,
;  затирая соседнюю память.
;
;  Процессор не считает это ошибкой. Для него нет никакого «буфера» —
;  есть адрес и есть инструкция записи. Понятие границы существует
;  только в голове программиста и в исходном тексте.
;
;  Это CWE-787 «Out-of-bounds Write» — запись за границей буфера,
;  корневая причина классического переполнения буфера.
;
;  Отсюда следует главный вывод пары: на этом уровне безопасность
;  памяти целиком лежит на человеке. Языки из остальных трёх файлов
;  забирают эту ответственность себе — каждый в своей мере.
; ===========================================================================
