Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Работа СОМ-программы

Вопрос:
Никак не могу разобраться в примере Главы 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.

   Вперёд
   Содержание