# yes_pie.S - PIE-совместимая версия
.intel_syntax noprefix
.global _start

.section .text
_start:
    # Получаем argc и argv
    pop     rcx              # argc
    pop     rdi              # argv[0] (пропускаем)
    
    # Определяем строку для вывода
    cmp     rcx, 2
    jl      .Ldefault
    
    pop     rsi              # argv[1]
    jmp     .Lprepare
    
.Ldefault:
    # RIP-relative addressing для default_str
    lea     rsi, [rip + default_str]
    
.Lprepare:
    mov     r12, rsi         # сохраняем указатель на строку
    
    # Вычисляем длину строки
    mov     rdi, r12
    mov     rcx, -1
    xor     al, al
    repne   scasb
    not     rcx
    dec     rcx
    mov     r13, rcx         # r13 = длина строки
    
    # Длина с \n
    mov     r14, r13
    inc     r14
    
    # Выделяем буфер 32KB на стеке
    sub     rsp, 32768
    mov     rbx, rsp         # rbx = указатель на буфер
    
    # Заполняем буфер
    mov     rdi, rbx
    mov     rbp, rbx
    add     rbp, 32768
    
.Lfill:
    # Копируем строку
    mov     rsi, r12
    mov     rcx, r13
    rep     movsb
    
    # Добавляем '\n'
    mov     byte ptr [rdi], 10
    inc     rdi
    
    # Проверяем, не вышли ли за пределы буфера
    cmp     rdi, rbp
    jb      .Lfill
    
    # Вычисляем реальный размер
    mov     rdx, rdi
    sub     rdx, rbx
    
    # Основной цикл вывода
.Lwrite:
    mov     rax, 1           # SYS_write
    mov     rdi, 1           # STDOUT_FILENO
    mov     rsi, rbx
    syscall
    
    cmp     rax, 0
    jle     .Lexit
    jmp     .Lwrite
    
.Lexit:
    xor     rdi, rdi
    mov     rax, 60          # SYS_exit
    syscall

.section .rodata
default_str: .asciz "y"
