Из 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