Вопрос или проблема
Работаю в 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
Заключение
С учетом вышеизложенных предложений и изменений вы сможете более эффективно писать данные в текстовый файл. Убедитесь, что ваш код учитывает все возможные ошибки при работе с файлами. Также советую регулярно тестировать каждую часть функции, чтобы быстро находить и исправлять возникающие ошибки, улучшая качество кода в целом.