 |
Ассемблер в примерах - Работа СОМ-программы
- Вопрос:
- Никак не могу разобраться в примере Главы 9 (prog009.asm).
На мой взгляд программа должна работать следующим образом:
1. Процедура открытия файла происходит таким образом: сравнивает значение Handle с двойным словом 0FFFFh, т.к. они неравны то переходим к Quit_open: и устанавливаем флаг переноса в 1 (stc) затем ret возвращаемся на строчку ниже после вызова call на jc Error_file и т.к. флаг переноса =1, то переходим на закладку Error_file: при достижения возврата возвращаемся обратно на jc Error_File и опять все заново на Error_file....Помогите разобраться.
Prog09.asm
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
Begin:
mov dx,offset File_name
call Open_file
jc Error_file
; -------------Открыли файл ----------------
mov bx,ax
mov ah,3Fh
mov cx,offset Finish-100h
mov dx,offset Begin
int 21h
; -------------Прочитали файл ----------------
call Close_file
; ------------Выводим сообщение --------------
mov ah,9
mov dx,offset Mess_ok
int 21h
ret
; ----------Не смогли открыть файл-----------------
Error_file:
mov ah,2
mov dl,7
int 21h
ret
; ===ПРОЦЕДУРЫ ===
; --- Открытие файла ---
Open_file proc
cmp Handle,0FFFFh
jne Quit_open
mov ax,3D00h
int 21h
mov Handle,ax
ret
Quit_open:
stc
ret
Handle dw 0FFFFh
Open_file endp
; --- Закрытие файла ---
Close_file proc
mov ah,3Eh
mov bx,Handle
int 21h
ret
Close_file endp
; ===ДАННЫЕ===
File_name db 'prog09.com',0
Mess_ok db 'Всё нормально!', 0Ah, 0Dh, '$'
Finish equ $
CSEG ends
end Begin
- Ответ:
-
1) У Вас СОМ-программа, об этом говорит директива org 100h
Этот тип испоняемых файлов имеет размер до 64кб, размещается в памяти в одном сегменте, всегда начинается с адреса 100h.
Практически предтсавляет собой снимок(dump) памяти одного сегмента. А также не имеет заголовка программы. Его подставляет стандартный загрузчик DOS. При загрузке программы в память регистр SP(указатель стека)имет значение 0FFFEh - адрес вершины доступной памяти, а также по этому адресу всегда записывается значение 0000h.
При выполнении любой команды возврата(RET) из приведенного кода:
mov ah,9
mov dx,offset Mess_ok
int 21h
ret
Error_file:
mov ah,2
mov dl,7
int 21h ret
Из стека будет извлекатся значение 0000h и передаватся управление по этому адресу(CS:0000), а там находится стандартный заголовок программы, подставленый DOSом и записана там команда INT 20h(CDh 20h) - вызов функции DOS "завершить процесс". Именно поэтому и опять все заново на Error_file не будет.
2)При компиляции программы Handle dw 0FFFFh эта переменная будет иметь значение -1(0FFFFh). При запуске программы и первом вызове подпрограммы Open_file , команда сравнения ( cmp Handle,0FFFFh ) будет сравнивать с тем значением которое туда записал компилятор, после открытия файла в эту переменную будет записано совершенно другое значение, но только не 0FFFFh.
|  |