Из 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
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д