Запись пикселей в числа [hex] в asm txt

Вопрос или проблема

введите описание изображения здесь

Работаю в asm x8086. Это область рисования пикселей с цветами, используя клавиши, и я могу выбирать цвета, поэтому я просто хотел сохранить холст, чтобы позже импортировать его.


SaveCanva PROC
    MOV AH, 3Ch
    MOV CX, 0
    LEA DX, fileName
    INT 21h
    JC handleError
    MOV HANDLER, AX
    MOV CX, yStart
yLoop:
    CMP CX, yEnd
    JA endProgram
    MOV SI, 0
    MOV DI, 0
    MOV BX, 0
writeLoop:
    MOV AX, CX
    MOV DX, BX
    MOV AH, 0x0C
    INT 10h
    CALL GetHexValue
    MOV buffer[DI], AL
    INC DI
    INC BX
    CMP BX, 80
    JL writeLoop
    MOV buffer[DI], '@'
    INC DI
    MOV AH, 40h
    MOV BX, HANDLER
    MOV CX, DI
    LEA DX, buffer
    INT 21h
    INC CX
    JMP yLoop
endProgram:
    MOV AL, '%'
    MOV buffer[0], AL
    MOV CX, 1
    MOV AH, 40h
    MOV BX, HANDLER
    LEA DX, buffer
    INT 21h
    MOV AH, 3Eh
    MOV BX, HANDLER
    INT 21h
    RET
handleError:
    RET

  GetHexValue PROC NEAR
    CMP AL, 0
    JE .black

    CMP AL, 1
    JE .blue

    CMP AL, 2
    JE .green

    CMP AL, 3
    JE .cyan

    CMP AL, 4
    JE .red

    CMP AL, 5
    JE .magenta

    CMP AL, 6
    JE .brown

    CMP AL, 7
    JE .light_gray

    CMP AL, 8
    JE .dark_gray
    
    CMP AL, 9
    JE .light_blue

    CMP AL, 10
    JE .light_green

    CMP AL, 11
    JE .light_cyan

    CMP AL, 12
    JE .light_red

    CMP AL, 13
    JE .light_magenta

    CMP AL, 14
    JE .yellow

    CMP AL, 15
    JE .white

    RET

  .black: 
    MOV AL, '0' 
    RET

  .blue:  
    MOV AL, '1' 
    RET

  .green: 
    MOV AL, '2' 
    RET

  .cyan:  
    MOV AL, '3' 
    RET

  .red:   
    MOV AL, '4' 
    RET

  .magenta:  
    MOV AL, '5' 
    RET

  .brown: 
    MOV AL, '6' 
    RET

  .light_gray: 
    MOV AL, '7'
    RET

  .dark_gray: 
    MOV AL, '8' 
    RET

  .light_blue:
    MOV AL, '9' 
    RET

  .light_green: 
    MOV AL, 'A' 
    RET

  .light_cyan:
    MOV AL, 'B' 
    RET

  .light_red: 
    MOV AL, 'C' 
    RET

  .light_magenta: 
    MOV AL, 'D' 
    RET

  .yellow: 
    MOV AL, 'E' 
    RET

  .white: 
    MOV AL, 'F' 
    RET

GetHexValue ENDP

Я пробовал в графическом режиме 12h [640×480, 16 бит], чтобы получить каждый пиксель от начала до конца, я хочу сохранить это в текстовом файле, но я пытался преобразовать цвет пикселя в его эквивалент в шестнадцатеричном формате и затем сохранить это в текстовом файле, но он не записывает в TXT файл, почему? Я пытался использовать ‘@’ в конце каждой строки и ‘%’ для обозначения конца файла, но проблема в том, что ничего не сохраняется, я даже пытался сохранить пустой холст, потому что, по крайней мере, файл был бы заполнен 0, но даже этого не записывает в текстовый файл.

Ответ или решение

Сохранение пикселей в текстовом файле на Assembler (x86)

Проблема, с которой вы столкнулись, заключается в том, что, несмотря на то, что ваш код предназначен для преобразования цветов пикселей в их шестнадцатеричное представление и сохранения их в текстовом файле, фактическое сохранение данных не работает так, как было задумано. Ваша программа использует прерывание INT 21h для работы с файлами на MS-DOS, однако есть несколько замечаний и рекомендаций, которые могут помочь вам правильно сохранить данные в файл.

1. Обработка ошибок при открытии файла

В вашем коде есть описание обработки ошибок, но стоит убедиться, что вы корректно обрабатываете все возможные коды ошибок, возвращаемые при работе с файлами. Особенно важно правильно обработать возвращаемый AX после вызова INT 21h для создания файла. Если файл не был создан, корректно отработайте этот случай, например, выведите соответствующее сообщение об ошибке.

2. Запись данных

Ваш код включает логику для записи данных, но следует проверить несколько важных моментов:

  • Убедитесь, что массив buffer определен и выделено достаточно памяти, чтобы в него поместились все данные. Обычно размер одного буфера должен соответствовать количеству строк, умноженному на 80 (ширина экрана в текстовом режиме).

  • Актуальная длина строки в buffer должна учитываться. Вы корректно используете знак ‘@’ для обозначения конца строки. Убедитесь, что DI — индекс, в который ведется запись, всегда корректен.

3. Корректное получение значения цвета пикселя

Ваша процедура GetHexValue отвечает за преобразование значений цвета, однако нужно убедиться, что переменная, передаваемая в AL, корректна. Например, если вы используете графический режим 0x12 (640×480), то значение цвета может отличаться от ожидаемого в текстовом режиме. Убедитесь, что вызов INT 10h действительно возвращает ожидаемые значения цветов для текущего графического режима.

4. Завершение работы и очистка ресурсов

В конце вашей процедуры сохранения канвы не забудьте закрыть файл с помощью вызова INT 21h с функцией 3Eh, чтобы гарантировать, что все данные будут записаны корректно и файл не останется открытым.

Пример исправленного кода

Принимая во внимание вышеизложенные пункты, вот исправленная версия вашего кода для сохранения канвы:

SaveCanva PROC
    MOV AH, 3Ch            ; Открыть файл для записи
    MOV CX, 0              ; Сбросить счетчик
    LEA DX, fileName       ; Указать имя файла
    INT 21h
    JC handleError
    MOV HANDLER, AX        ; Сохранить дескриптор файла

    MOV CX, yStart         ; Начальная координата Y
yLoop:
    CMP CX, yEnd           ; Проверка конца диапазона по Y
    JA endProgram

    MOV SI, 0
    MOV DI, 0

writeLoop:
    MOV AX, CX             ; Получаем текущую координату Y
    MOV DX, BX             ; Получаем текущую координату X
    MOV AH, 0x0C          ; Получаем цвет пикселя
    INT 10h                ; Прерывание для графики
    CALL GetHexValue       ; Получаем шестнадцатеричное значение

    MOV buffer[DI], AL     ; Сохранение цвета в буфер
    INC DI
    INC BX
    CMP BX, 80             ; Проверка ширины строки
    JL writeLoop

    MOV buffer[DI], '@'    ; Конец строки
    INC DI
    MOV AH, 40h            ; Запись в файл
    MOV BX, HANDLER        ; Дескриптор файла
    MOV CX, DI             ; Длина данных
    LEA DX, buffer         ; Адрес данных
    INT 21h                ; Вызов записи

    INC CX                  ; Увеличиваем счетчик Y
    JMP yLoop              ; Переход к следующей строке

endProgram:
    MOV AL, '%'            ; Индикатор конца файла
    MOV buffer[0], AL
    MOV CX, 1
    MOV AH, 40h
    MOV BX, HANDLER
    LEA DX, buffer
    INT 21h

    ; Закрываем файл
    MOV AH, 3Eh            ; Закрытие файла
    MOV BX, HANDLER
    INT 21h
    RET

handleError:
    ; Обработка ошибок
    RET

Заключение

С учетом вышеизложенных предложений и изменений вы сможете более эффективно писать данные в текстовый файл. Убедитесь, что ваш код учитывает все возможные ошибки при работе с файлами. Также советую регулярно тестировать каждую часть функции, чтобы быстро находить и исправлять возникающие ошибки, улучшая качество кода в целом.

Оцените материал
Добавить комментарий

Капча загружается...