Консультация № 191523
23.10.2017, 21:06
0.00 руб.
0 8 1
Уважаемые эксперты, здравствуйте,
у меня возникли вопросы по главе 9 книги О.А.Калашникова,

листинг 9.3 и листинг 10.1,
1) call Open_file
jc Error_file

процедура (subroutine в Фортране или функция в Си) Open_file:
Код:
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

вопросы -
а) зачем нужна строка "cmp Handle,0FFFFh", когда переменная Handle уже инициализирована в этой процедуре-сабрутине-функции и ей уже присвоено значение 0FFFFh ?
б) ведь Handle - это всего лишь переменная, а не регистр ?
в) что означает шестнадцатиричное число 0FFFFh ? это адрес стэка ? адрес начала или конца стэка (последний зашел - первый вышел) ?

2)
Код:
mov cx,offset Finish-100h
mov dx,offset Begin
int 21h

здесь Finish - это адрес первого свободного байта сразу же после конца данной ассемблеровской com-программы. это я понимаю.
далее - 100h - это адрес, в CS-сегменте (сегменте кода), первой строки данной com-программы.
вопросы -
а) означает ли это, что строки
Код:
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
Begin:

не занимают никакой памяти в com-файле, а предназначены лишь как инструкции для самого Ассемблера-компилятора, нежели для микропроцессора ?
б) что находится в первых от 0h до 0FFh байтах в полученном исполняемом com-файле ? либо поставим вопрос по-другому - данная исполняемая com-програма (файл) начинается с ассемблеровских инструкций сразу же после метки "Begin:" ? а когда данный com-файл загружается из ПЗУ в ОЗУ - сразу же после выдачи команды "prog09.com" в Dos-овской оболочке и соответственно после нажатия клавиши "Enter", то именно в ОЗУ (а не в самом com-файле) первые байты с коде сегмента CS, от 0h до 0FFh, заняты чем-то ? чем-именно ? эти первые байты заняты чем-то только для модели tiny ?
в) "Finish-100h" - это мне понятно:
это размер в количестве байта данной com-программы - от
"mov dx, offset File_name" и до "end Begin". правильно ли я это понимаю ?

3)
Код:
call Close_file
; ------------ Выводим сообщение --------------
mov ah,9
mov dx,offset Mess_ok
int 21h
ret

вопрос - почему используется команда "ret", а не "int 20h" ?

Спасибо.

Обсуждение

давно
Старший Модератор
31795
6196
24.10.2017, 10:24
общий
24.10.2017, 10:37
Адресаты:
0)
Перестаньте называть подпрограммы в разных интерпритациях
Цитата: Ильдар Рифович Альмиев
subroutine в Фортране или функция в Си

Смысл одинаков, некоторый код выделен в отдельный логический блок, с разницей, что первая не возвращает параметр, вторая - да. Не смотря на то в ЯВУ С всё есть функция, все таки есть Fortran'новские и subroutine и function. Различия определяются типом возвращаемого параметра. VOID - определяет процедуру.


1)
0FFFFh - это уникальное число равное -1, такое же как и 00000h, это число(-1) не может быть дескриптором или указателем на открытый файл.
И.В. Вам не все рассказал о файлах в прошлый раз. Функций работы с файлами больше.

Чтобы было понятно на рисунке идут номер в 16-ой системе, в 10-ой, называние функции, версия ДОС и тип функции.
F(file control block- FCB) и H(handle- дескриптор).
В первых версиях ДОС, программа должна была сама хранить информацию об открытых файлах в FCB, это было не удобно, т.к. приходилось постоянно перепрыгивать от одного к другому, меняя указатель на FCB. Начиная со второй версии ОСь, взяла на себя хранение такой информации, предоставляя пользователю, только указатель(возможно индекс в массиве структур ) на структуру аналогичную FCB.


В данном случае -1 используется как флаг открытия файла, если там другое число - файл открыт.

2)
а - эти строки сокращенно описывают сегмент(CSEG segment), указывают компилятору относительно каких сегментных регистров генерировать код по умолчанию(assume), размещение кода в памяти(org 100h)

б - по этим адресам (от 0h до 0FFh) находится стандартный префикс программы, подставляемой системой при запуске.

в - Finish - адрес конца кода в памяти, 100h - адрес начала кода в памяти. Итого вычисляется длина кода в памяти, без префикса программы.

3)
Кроме стандартного префикса программы система ещё заносит в стек 00000h и когда будет выполнено команду RET, то управление будет передано на адрес CS : 00000h, а там int 20h
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
24.10.2017, 11:43
общий
Адресаты:
Почитайте про PSP (program segment prefix, сегмент программного префикса)
Первые 100h содержат указанную информацию. Забегая вперед, начиная с адреса 80h там же лежит строка параметров, передаваемая программе в командной строке.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401339
51
24.10.2017, 18:38
общий
24.10.2017, 18:39
Адресаты:
Уважаемые Константин Николаевич и Игорь Витальевич,
добрый вечер,

1) спасибо большое за Ваши ценные сообщения-консультации.

2) конечно, я попытаюсь исправиться в следующий раз - ассемблеровские подпрограммы называть подпрограммами, а не брать аналогию из Фортрана (subroutine, function) и из Си (void/int/float/double/complex функции) - тем не менее такие аналогии полезны всего-лишь для понимания сути дела в Ассемблерах - для новичков, изучающих Ассемблеры.

Константин Николаевич, я понимаю, что Вы являетесь экспертом-профессионалом в военной электронике и программировании военного "железа" (hardware) и подкованы как в теории так и в практике - поэтому я приношу лично Вам свои извинения за Си-Фортран-овские аналогии - впредь попытаюсь Вас заранее предупреждать на мини-форумах, что такие аналогии необходимы мне только для понимания сути дела в Ассемблерах. Б-га ради извините, если я чем-то Вас лично обидел или затронул Ваши профессиональные чувства.

3) "...Функций работы с файлами больше..."

F(file control block- FCB) и H(handle- дескриптор) - что обозначают данные понятия-термины применительно к ассемблеровским функциям (действиям - использую данный термин для понимания), связанными с файлами ?

4) насколько я понимаю, данные файловые функции должны записываться в регистр AX. не так ли ?

5) в дальнейшем попытаюсь поэкспериментировать-"поиграть" с данными файловыми функциями.

Спасибо.
давно
Старший Модератор
31795
6196
24.10.2017, 19:16
общий
Адресаты:
Цитата: Ильдар Рифович Альмиев
F(file control block- FCB) и H(handle- дескриптор) - что обозначают данные понятия-термины применительно к ассемблеровским функциям (действиям - использую данный термин для понимания), связанными с файлами ?

Структуру FCB, я Вам дал. Работа с файлами функциями F(см. таблицу)происходит с помощью этой структуры.
Работа с функциями H, проще, но система о существовании FCB не забыла, т.к. она используется функциями найти первый/найти следующий файл.
Практически все функции, которые Вы будете использовать параметры имеют следующие значения:
AH - номер функции данного прерывания(но не всегда);
(остальные регистры могут и не использоваться, поэтому нужно смотреть описание самой функции)
AL - иногда это может быть как параметр(аргумент), так и номер подфункции;
BX - в разных функциях имеет разное значение;
CX - обычно указывает на количество каких-то значений;
DX - обычно указывает на какой-то участок памяти, с которым должна отработать функция.

Советую найти в сети книгу Данкан Р. Профессиональная работа в MS-DOS, ней расписаны основные функции прерываний BIOS и DOS, на русском.
Все описания выглядят так:

(саму функцию выбрал на угад, просто обратите внимание на подачу информации).


Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401339
51
25.10.2017, 01:04
общий
25.10.2017, 01:05
Адресаты:
Уважаемый Константин Николаевич,
доброй ночи,

1) спасибо за Ваше сообщение-консультацию.

2) на данный момент я пока не разобрался в F(file control block- FCB) и H(handle- дескриптор), хотя для Вас это выглядит очень элементарной информацией - я обязательно найду в Интернете рекомендуемую Вами книгу Р.Данкана, после ознакомления с которой и с помощью консультаций с Вами в будущем, надеюсь, что разберусь в данной теме.

3) а пока ... FCB - это область (блок) памяти ? где ? в ОЗУ ?
Код:
В первых версиях ДОС, программа должна была сама хранить информацию об открытых файлах в FCB, ... 

допустим имеется com-программа, которая читает файл и имеется первая версия DOS. где находится FCB ? это com-программа также имеет дополнительные блоки FCB ?

4)
Код:
... это было не удобно, т.к. приходилось постоянно перепрыгивать от одного к другому, меняя указатель на FCB.

значит для каждого открытого файла создавался-резервироовался в памяти свой блок FCB (см. картинку выше), не так ли ?
что значит "постоянно перепрыгивать от одного к другому" (от одного файла к другому ?) и что значит "меняя указатель на FCB" ?
Константин Николаевич, пожалуйста поясните подробнее вопросы из пункта 4).

Спасибо.
давно
Старший Модератор
31795
6196
25.10.2017, 11:18
общий
Адресаты:
Представим связку компьютер-пользователь в виде цепочки(в подробности самой работы не рассматриваем, только общее представление):


Биос работает с железом на уровне портов, предоставляя свои функции и устанавливает свои обработчики.
ОСь работает посредством функций биос, или игнорируя их, с помощью портов с железом, предоставляя свои функции и добавляя свои обработчики в вершину цепочки обработчиков данного прерывания или заменяя их своими.
Программа пользователя может работать с функциями ОСи, биос, или прямо с железом, устанавливая нужные себе обработчики в вершине цепочек обработчиков.

Теперь представим, пользователь нажал клавишу, сработал аппаратный обработчик клавиатуры(к примеру программы пользователя, его адрес записан в таблице прерываний 0х0000:0х0024). Если он не обрабатывает данное событие, то передает управление обработчику, который был раньше, в упрощенном варианте, это обработчик ОСи, если и он не обрабатывает, то управление получает обработчик биос. Если один из обработчиков нашел свое событие, то он записывает обработанные данные в область данных программы/служебные области своего уровня, из которых потом они читаются кодом(функциями) данного уровня. Вот такая примерная цепочка событий.

FCB:
Рассмотрим функцию DOS чтение открытого файла:
AH = 3Fh
BX = file handle
CX = number of bytes to read
DS:DX -> buffer for data
Return:
CF clear if successful
AX = number of bytes actually read (0 if at EOF before call)
CF set on error
AX = error code

и функцию BIOS чтение накопителя НГМД(дискета) или HDD
AH = 02h
AL = number of sectors to read (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
Return:
CF set on error
if AH = 11h (corrected ECC error), AL = burst length
CF clear if successful
AH = status
AL = number of sectors transferred (only valid if CF set for some BIOSes)

Заметили, что они работают на разных уровнях биос работает на уровне цилиндров-дорожек-секторов(ЦДС -физическое расположения файла на диске), ОСь это скрывает от программиста подменяя дескриптором всю работу:
-получение имени файла;
-чтение таблицы FAT(как более простая версия файловой системы, в качестве примера), если глубоко не копать, находится имя файла, его расширение, его атрибуты, размещение на диске, т.е. физический адрес в формате ЦДС;
- нахождение нужного имени в таблице FAT;
- проверка прав доступа;
- получение данных ЦДС;
- чтение минимум одного сектора, т.е. 512 байт, и это не смотря на то, что пользователь может захотеть читать файл по одному байту(кластеризацией пока мозги не грузим).

Думаю, что даже этого достаточно, хотя и это далеко не всё. Так вот FCB как раз хранит временную информацию об открытом файле упрощая работу системе. ОСь при открытии файла заполняет эту таблицу, потом только обращается к ней сразу получает нужную информацию. В первых версиях DOS хранение FCB ложилось на программиста, начиная со второй версии ОСь предоставляла пользователю дескриптор (который может быть как адресом блока FCB в служебной области, так и индексом в некотором массиве блоков FCB)
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
25.10.2017, 16:30
общий
это ответ
Здравствуйте, ialmiev!

1)
При открытии файла, в переменную Handle записывается некоторое число-дескриптор, по которому ОСь однозначно идентифицирует данный файл. Это число не может быть 0-4(stdin, stdout, stderr, stdaux, stdprn) -значения соответственно уже зарезервированы, поигравшись с файлами-дескрипторами (три последовательно открытых файла имеют последовательные номера, т.е. это индексы некоторого массива управляющих файлами структур операционной системы) и величина ограниченна значением системной переменной FILES в файле config.sys и максимальное значение равно 255.
0хFFFF - уникальное число(-1 или 65535), т.к. такое число одновременно открытых файлов система не даст открыть.

2)
[code lang=asm]CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
Begin:[/code]
Эти строки - директивы компилятора, они участвуют только в процессе создания кода:,
- 1) описывает сегмент памяти как отдельный логический блок, это сокращенная запись от записи:
имя_сегмента segment readonly выравнивание. тип разряд 'класс'
имя_сегмента segment - сокращенная запись;
readonly - опция директивы, которая, заставляет MASM(другим без разницы) выдавать сообщение о попытке записи в этот сегмент;
выравнивание - опция указывающая компилятору с какого адреса может начинаться сегмент, обычно PARA - 16-ть байт, т.к. меньше не имеет смысла из-за особенностей формирования физического адреса;
тип - опция, которая указывает можно ли и как комбинировать сегменты между собой;
разряд - 16-ть или 32-а битный сегмент;
'класс' - может быть любое имя в кавычках, все сегменты с одинаковым классом, будут расположены друг за другом;
- 2) указывает компилятору, что данный сегментный регистр связывается с таким-то сегментом или группой сегментов;
- 3) указывает компилятору, с какого адреса генерировать код.

Сейчас используется упрощенные директивы: .CODE, .DATA, .STACK, вместе с указанием модели памяти: .MODEL TINY | SMALL | FLAT.

В памяти от 0h до 0FFh находится префикс программы, для данной модели памяти(tiny) он одинаков для всех сом-файлов и подставляется автоматически системой. Это сложилось исторически, когда компьютеры были маленькие и места чтобы хранить в каждой программе аж 256 байт не было.

В данной строке вычисляется длина самого кода, от последнего адреса программы вычитается длина префикса программы(см. выше).

3)
Вместе с префиксом программ система ещё защищает себя, она автоматически в стек записывает код 0х0000, когда клавиатурный маньяк случайно завалит стек и очередной раз выполнит команду RET, то управление получит код по адресу CS : 0000, а там команда INT 20h.

Удачи!
5
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401339
51
26.10.2017, 02:47
общий
26.10.2017, 02:48
Адресаты:
Уважаемый Константин Николаевич,
здравствуйте,

1) спасибо большое за Ваши ценные сообщения-консультации. уверен, что они (консультации) обязательно пригодятся мне в будущем. полагаю, что у меня в дальнейшем-будущем возникнут вопросы по БИОС и ОС (любой) и по их дизайну и разработке. но к этому мне нужно идти последовательно-постепенно, начиная с простого и затем постепенно усложняя материал-информацию.

2) пока же я продолжу изучать книгу О.А.Калашникова для практики и набиванию-тренировке своих рук по Ассемблеру MASM.

3) Константин Николаевич, я сожалею, что мои профессиональные навыки по атомной и лазерной физике не нужны в настоящее время и, также, мой научный труд практически не оплачивается ни в России, ни на Западе.
однако ничего не поделаешь - приходится переучиваться с нуля для того чтобы в дальнейшем встать на уровень профессиональных решений низкоуровневого программирования и работы с "железом", включая электронику-схемотехнику.

4) Константин Николаевич, как специалист по военной электронике, можете ли Вы порекомендовать мне Форум(ы) для новичков (начиная с азов - как функционируют транзисторы и диоды, рабочая точка транзисторов, зачем нужна стабилизация по току и т.д.) для обсуждения вопросов по электронике-схемотехнике ?

Спасибо, еще раз, за Ваши консультации и Ваше взаимопонимание.
Форма ответа