section .data
    number dw 5      ; Число для инвертирования бита

section .text
    global _start

_start:
    ; Инвертируем 4-й бит

    mov ax, [number]   ; Загружаем число из секции данных в регистр AX
    xor ax, 0x0010     ; Инвертируем 4-й бит (0x0010 = 00000000 00010000b)

    ; Выводим младший байт в шестнадцатеричном виде
    movzx eax, al      ; Расширяем AL (младший байт AX) до EAX, заполняя нулями
    push eax           ; Сохраняем значение EAX в стек для передачи в функцию печати
    call print_hex     ; Вызываем функцию печати в шестнадцатеричном виде
    add esp, 4         ; Очищаем стек после вызова функции

    ; Завершение программы
    mov eax, 1         ; Системный вызов exit
    xor ebx, ebx       ; Код возврата 0
    int 0x80           ; Вызов ядра

; Функция для печати числа в шестнадцатеричном виде (младшего байта)
print_hex:
    push ebp           ; Сохраняем старое значение EBP
    mov ebp, esp       ; Устанавливаем EBP на вершину стека
    push ebx           ; Сохраняем регистры, которые будем использовать

    mov eax, [ebp+8]   ; Получаем число из стека

    ; Вывод старшей цифры (4 бита)
    mov bl, al          ; Копируем AL в BL
    shr bl, 4           ; Сдвигаем вправо на 4 бита, чтобы получить старшую цифру
    and bl, 0x0F       ; Маскируем, чтобы оставить только 4 младших бита
    call print_digit    ; Вызываем функцию печати цифры

    ; Вывод младшей цифры (4 бита)
    mov bl, al          ; Копируем AL в BL
    and bl, 0x0F       ; Маскируем, чтобы оставить только 4 младших бита
    call print_digit    ; Вызываем функцию печати цифры

    pop ebx            ; Восстанавливаем регистры
    pop ebp            ; Восстанавливаем старое значение EBP
    ret                ; Возврат

; Функция для печати одной шестнадцатеричной цифры
print_digit:
    push ebp
    mov ebp, esp

    cmp bl, 0x0A       ; Сравниваем с 10 (A)
    jl  is_number       ; Если меньше 10, это цифра 0-9
    add bl, 0x37       ; Если больше или равно 10, это буква A-F (добавляем 'A' - 10 + '0')
    jmp print

is_number:
    add bl, 0x30       ; Преобразуем цифру в ASCII код

print:
    mov eax, 4         ; Системный вызов write
    mov ebx, 1         ; stdout
    mov ecx, esp       ; Адрес символа для вывода
    mov edx, 1         ; Количество байт для вывода
    int 0x80           ; Вызов ядра

    pop ebp
    ret
