Из COM в EXE - Assembler
Формулировка задачи:
Пытался переделать, но при компиляции выводит предупреждение No Stack, EXЕ то запускается, но программа не работает, подскажите что исправить.Компилирую в TASM
Вот код COM:
Вот EXE, который я пытался сделать:
Листинг программы
- .model tiny
- .code
- ORG 100h
- .386
- start:
- MOV DX,offset mess0
- CALL MESSAGE
- ;------------------- юзер вводит имя файла,
- ;------------------- а мы его сохраняем --------------------------//
- MOV DI,offset fName ; DI для STOSB...
- fileName: ;
- MOV AH,1 ;
- INT 21h ; читаем символ
- CMP AL,13 ; выход по ENTER
- JE next ;
- STOSB ; пишем символы в "ФайлНэйм"
- JMP fileName ;
- next: ;
- MOV AX,3D02h ; открыть файл! -----------------------//
- MOV DX,offset fName ;
- INT 21h ;
- JC error ; ошибка?
- XCHG AX,BX ; дескриптор файла в ВХ
- MOV AH,3Fh ; читать файл! ------------------------//
- MOV DX,offset buff ; куда,
- MOV CX,0FFFFh ; и сколько
- INT 21h ;
- JC error ;
- MOV [fSize],AX ; размер файла в переменной
- MOV AH,3Eh ; fucking file! -----------------------//
- INT 21h ;
- JC error ;
- MOV DX,offset mess1 ; покажем ОК! -------------------------//
- CALL MESSAGE ;
- MOV AX,[fSize] ; ..с размером файла
- MOV BX,10 ; в 10-тичной системе
- CALL HEX2ASC ;
- MOV DX,offset mess2 ; запрос на ввод ключа шифрования -----//
- CALL MESSAGE ;
- CALL ASC2HEX ;
- MOV [key],CL ; ключ в переменной
- MOV CX,[fSize] ; ..байтов для шифрования
- MOV SI,offset buff ; источник
- MOV BL,[key] ; ключ шифрования
- crypt: ;
- MOV AL,BYTE[SI] ; берём байт
- XOR AL,BL ; "ксорим" его ключом<------------------------------------------------XOR\SUB
- MOV BYTE[SI],AL ; и записываем обратно на место
- INC SI ; следующий байт..
- LOOP crypt ;
- MOV DX,offset mess3 ; мессага ОК!
- CALL MESSAGE ;
- CALL @@01 ; создаём новый файл ------------------//
- DB 'DATFILE.TXT',0 ;
- @@01: ;
- MOV AH,3Ch ;
- POP DX ; имя файла в DX
- MOV CX,20h ; атрибут - архивный
- INT 21h ;
- JC error
- XCHG BX,AX ; дескриптор файла в BX
- MOV AH,40h ; запись в файл -----------------------//
- MOV DX,offset buff ;
- MOV CX,[fSize] ; кол-во выводимым символов
- INT 21h ;
- JC error ;
- MOV AH,3Eh ; fucking file! -----------------------//
- INT 21h
- MOV DX,offset mess4 ; мессага "Создали Файл!"
- CALL MESSAGE ;
- JMP exit ;
- error: ; обработка ошибки --------------------//
- CALL @@@
- DB 13,10,7,'<--ERROR FILE OPERATION!$'
- @@@: ;
- POP DX ;
- CALL MESSAGE ;
- exit:
- XOR AX,AX ; выход!
- INT 16h ;
- INT 20h ;
- ;ннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн
- MESSAGE:
- MOV AH,9
- INT 21h
- RET
- ;//======= ФУНКЦИЯ ВЫВОДИТ НА ЭКРАН В РАЗЛИЧНЫХ СС ================|
- HEX2ASC:
- PUSHA ; перевод из HEX в ASCII и вывод на экран
- XOR CX,CX ; вход: BX = система счисления, AX = число
- isDiv: ; выход: на экране
- XOR DX,DX ;
- DIV BX ;
- PUSH DX ;
- INC CX ;
- OR AX,AX ;
- JNZ isDiv ;
- isOut: ;
- POP AX ;
- CMP AL,9 ;
- JLE noHex ;
- ADD AL,7 ; коррекция для HEX..
- noHex: ;
- ADD AL,30h ;
- INT 29h ; выводим символ на экран
- LOOP isOut ;
- POPA ;
- RET
- ;//========= ПРОЦЕДУРА СОХРАНЕНИЯ ВВОДА В HEX-ФОРМАТЕ =============|
- ASC2HEX:
- XOR CX,CX ; выход: CX = число
- @0: ;
- MOV AH,1 ; ввод с эхом
- INT 21h ;
- CMP AL,13 ; выход по ENTER
- JE stop ;
- SUB AL,30h ;
- CMP AL,9 ;
- JBE @2 ;
- SUB AL,11h ; значит HEX-буква. Отнимаем от неё фактор
- CMP AL,5 ; если заглавная буква, то остаток будет
- JBE @1 ; в пределах(5). Ниже/равно - коррекция!
- SUB AL,20h ; значит прописная буква. Коррекция..
- @1: ;
- ADD AL,10 ; коррекция букв "A..F", в "11..15"
- @2: ;
- SHL CX,4 ; сдвигаем мл.тетраду(CL), в старшую
- OR CL,AL ; в мл.тетраду(CL) запишем наше числ
- JMP @0 ;
- stop: ; результат в CX.
- RET
- mess0 DB 13,10,' READ FILE NAME......: $'
- mess1 DB 13,10,'<--OK! file size......: $'
- mess2 DB 13,10,10,' CRYPT MASK (byte)...: $'
- mess3 DB 13,10,'<--OPERATION COMPLETED!$'
- mess4 DB 13,10,'-----------------------------'
- DB 13,10,' CREATE "DATFILE.TXT" - OK!$'
- buff DB 1024 DUP(0) ; буфер для файла
- fName DB 16 DUP(0) ; имя файла (в формате 8.3)
- fSize DW 0
- key DB 0
- end start
Листинг программы
- .model tiny
- ORG 100h
- .386
- .data
- mess0 DB 13,10,' READ FILE NAME......: $'
- mess1 DB 13,10,'<--OK! file size......: $'
- mess2 DB 13,10,10,' CRYPT MASK (byte)...: $'
- mess3 DB 13,10,'<--OPERATION COMPLETED!$'
- mess4 DB 13,10,'-----------------------------'
- DB 13,10,' CREATE "DATFILE.TXT" - OK!$'
- buff DB 1024 DUP(0) ; буфер для файла
- fName DB 16 DUP(0) ; имя файла (в формате 8.3)
- fSize DW 0
- key DB 0
- .code
- start:
- MOV AX,@DATA
- MOV DS,AX
- MOV DX,offset mess0
- CALL MESSAGE
- ;------------------- юзер вводит имя файла,
- ;------------------- а мы его сохраняем --------------------------//
- MOV DI,offset fName ; DI для STOSB...
- fileName: ;
- MOV AH,1 ;
- INT 21h ; читаем символ
- CMP AL,13 ; выход по ENTER
- JE next ;
- STOSB ; пишем символы в "ФайлНэйм"
- JMP fileName ;
- next: ;
- MOV AX,3D02h ; открыть файл! -----------------------//
- MOV DX,offset fName ;
- INT 21h ;
- JC error ; ошибка?
- XCHG AX,BX ; дескриптор файла в ВХ
- MOV AH,3Fh ; читать файл! ------------------------//
- MOV DX,offset buff ; куда,
- MOV CX,0FFFFh ; и сколько
- INT 21h ;
- JC error ;
- MOV [fSize],AX ; размер файла в переменной
- MOV AH,3Eh ; fucking file! -----------------------//
- INT 21h ;
- JC error ;
- MOV DX,offset mess1 ; покажем ОК! -------------------------//
- CALL MESSAGE ;
- MOV AX,[fSize] ; ..с размером файла
- MOV BX,10 ; в 10-тичной системе
- CALL HEX2ASC ;
- MOV DX,offset mess2 ; запрос на ввод ключа шифрования -----//
- CALL MESSAGE ;
- CALL ASC2HEX ;
- MOV [key],CL ; ключ в переменной
- MOV CX,[fSize] ; ..байтов для шифрования
- MOV SI,offset buff ; источник
- MOV BL,[key] ; ключ шифрования
- crypt: ;
- MOV AL,BYTE[SI] ; берём байт
- XOR AL,BL ; "ксорим" его ключом<------------------------------------------------XOR\SUB
- MOV BYTE[SI],AL ; и записываем обратно на место
- INC SI ; следующий байт..
- LOOP crypt ;
- MOV DX,offset mess3 ; мессага ОК!
- CALL MESSAGE ;
- CALL @@01 ; создаём новый файл ------------------//
- DB 'DATFILE.TXT',0 ;
- @@01: ;
- MOV AH,3Ch ;
- POP DX ; имя файла в DX
- MOV CX,20h ; атрибут - архивный
- INT 21h ;
- JC error
- XCHG BX,AX ; дескриптор файла в BX
- MOV AH,40h ; запись в файл -----------------------//
- MOV DX,offset buff ;
- MOV CX,[fSize] ; кол-во выводимым символов
- INT 21h ;
- JC error ;
- MOV AH,3Eh ; fucking file! -----------------------//
- INT 21h
- MOV DX,offset mess4 ; мессага "Создали Файл!"
- CALL MESSAGE ;
- JMP exit ;
- error: ; обработка ошибки --------------------//
- CALL @@@
- DB 13,10,7,'<--ERROR FILE OPERATION!$'
- @@@: ;
- POP DX ;
- CALL MESSAGE ;
- exit:
- XOR AX,AX ; выход!
- INT 16h ;
- INT 20h ;
- ;ннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн
- MESSAGE:
- MOV AH,9
- INT 21h
- RET
- ;//======= ФУНКЦИЯ ВЫВОДИТ НА ЭКРАН В РАЗЛИЧНЫХ СС ================|
- HEX2ASC:
- PUSHA ; перевод из HEX в ASCII и вывод на экран
- XOR CX,CX ; вход: BX = система счисления, AX = число
- isDiv: ; выход: на экране
- XOR DX,DX ;
- DIV BX ;
- PUSH DX ;
- INC CX ;
- OR AX,AX ;
- JNZ isDiv ;
- isOut: ;
- POP AX ;
- CMP AL,9 ;
- JLE noHex ;
- ADD AL,7 ; коррекция для HEX..
- noHex: ;
- ADD AL,30h ;
- INT 29h ; выводим символ на экран
- LOOP isOut ;
- POPA ;
- RET
- ;//========= ПРОЦЕДУРА СОХРАНЕНИЯ ВВОДА В HEX-ФОРМАТЕ =============|
- ASC2HEX:
- XOR CX,CX ; выход: CX = число
- @0: ;
- MOV AH,1 ; ввод с эхом
- INT 21h ;
- CMP AL,13 ; выход по ENTER
- JE stop ;
- SUB AL,30h ;
- CMP AL,9 ;
- JBE @2 ;
- SUB AL,11h ; значит HEX-буква. Отнимаем от неё фактор
- CMP AL,5 ; если заглавная буква, то остаток будет
- JBE @1 ; в пределах(5). Ниже/равно - коррекция!
- SUB AL,20h ; значит прописная буква. Коррекция..
- @1: ;
- ADD AL,10 ; коррекция букв "A..F", в "11..15"
- @2: ;
- SHL CX,4 ; сдвигаем мл.тетраду(CL), в старшую
- OR CL,AL ; в мл.тетраду(CL) запишем наше числ
- JMP @0 ;
- stop: ; результат в CX.
- RET
- end start
Решение задачи: «Из COM в EXE»
textual
Листинг программы
- exit:
- XOR AX,AX ; выход!
- INT 16h
- MOV AH,4Ch ;
- INT 21h
Объяснение кода листинга программы
- XOR AX,AX — Код вычисляет логическое ИЛИ между регистрами AX и AX и сохраняет результат в обоих регистрах. Результат этого выражения всегда будет равен 0, потому что мы сравниваем одинаковые значения.
- INT 16h — Это команда прерывания, которая передает управление компьютеру для обработки функции, связанной с номером прерывания 16h. В IBM PC и совместимых системах номер прерывания 16h обычно используется для обращения к BIOS, чтобы выполнить действия, такие как загрузка операционной системы или выполнение операций ввода/вывода.
- MOV AH,4Ch — Эта команда перемещает значение 4Ch (что эквивалентно десятичному числу 72) в регистр AH. Регистр AH обычно используется в кодах прерываний для передачи информации в BIOS.
- INT 21h — Это еще одна команда прерывания, которая передает управление компьютеру для обработки функции, связанной с номером прерывания 21h. В IBM PC и совместимых системах номер прерывания 21h обычно используется для обращения к BIOS, чтобы выполнить действия, такие как загрузка операционной системы или выполнение операций ввода/вывода.
Код, представленный здесь, является простым примером и не выполняет какую-либо конкретную задачу. Он состоит из четырех команд:
- XOR AX,AX — выход из программы
- INT 16h — передача управления BIOS
- MOV AH,4Ch — передача значения 72 в регистр AH
- INT 21h — передача управления BIOS
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д