- •Билет 2 (Проверка открытия exe файла)
- •Клава.Асм
- •Выводит хвост командной строки
- •Породитель процесса (par.Asm)
- •Порождаемый процесс
- •Билет 3 (сканер для лексем)
- •Билет 4 (построить грамматику с возведением в степень)
- •Билет 5 (преобразование для нисходящего разбора)
- •Билет 7 (представление массива и выведение формулы)
- •Билет 8 (хеш - функция)
- •Билет 6 (грамматика для if then else)
- •Билет 9(Построить таблицу идентификаторов)
- •Билет 10 (ка для сканера лексем)
- •Билет 11(грамматика для чисел)
- •Билет 13 (матрица предшествования для грамматики)
- •Билет 14(анализ грамматики для метода предшествования)
- •Билет 16 (Заголовок exe)
- •Билет 17(Структура диска ms-dos)
- •Билет 18 (Синтаксический анализ теория) не написано Билет 19 (Лексический анализ теория)
- •Требования к грамматике нисходящего метода
- •Семантические программы. Перевод инфиксной записи в польскую.
- •Тетрады
- •Хранение грамматики с использованием сети
- •Аппаратные прерывания
- •Представление многомерных массивов в памяти эвм
- •Свободные кластеры логического диска "а" (на всякий)
Представление многомерных массивов в памяти эвм
Как правило хранятся в виде одномерного вектора. Это связано с тем, что при таком способе хранения формализуются способы поиска элементов массива. Различают хранение одномерных массивов:
-по столбцам [1];
-по строкам [2].
Рассмотрим это понятие на примере двухмерного массива.
a11 a12 a13
a21 a22 a23
a31 a32 a33
В [1] случае он хранится в виде:
a11 a21 a31 a12 a22 a32 a13 a23 a33.
Во [2] случае он хранится в виде:
a11 a12 a13 a21 a22 a23 a31 a32 a33.
Формула элемента имеет вид:
2) По строкам: Пусть массив имеет размерность n, rk - величина к-ого измерения массива, Indi - индекс к-ой размерности
тогда формула элемента массива имеет вид:
Свободные кластеры логического диска "а" (на всякий)
Вопрос:
Разработать ассемблер-программу,выводящую в файл номера свободных кластеров логического диска "А". Для вывода использовать handle-ориентированные системные функции обработки файлов. Формат вывода - символьно-шестнадцатеричный. Пояснить назначение выводимых объектов и их отдельных полей. Для поиска объектов использовать только прерывания 13h.
Ответ:
Программа в приложении. Единственно, что еще следовало бы добавить - обработку ошибок типа "не читается диск".
.model tiny ;буддем создавать com-файл .186 ;чтобы можно было было использовать команды shr ax,4 BOOT_STRUCTURE struc ;структура данных бутовой записи Jmp_Command db 3 dup (?) ;jmp Company_Name db 8 dup (?) ;производитель Sector_Size dw ? ;размер сектора в байтах Cluster_Size db ? ;размер кластера в секторах Reserved_Sectors dw ? ;количество резервных секторов (после бутовой записи и до FAT-а) FAT_Count db ? ;количество FAT-ов Root_Size dw ? ;размер корневого каталога в 32-байтных записях (в секторе 16 штук) Total_Sectors dw ? ;общее число секторов Media db ? ;тип носителя FAT_Size dw ? ;размер одного FAT-а в секторах Track_Sectors dw ? ;количество секторов на дорожке Heads_Count dw ? ;количество головок Hidden_Sectors dw ? ;невидимые сектора (на флоппи их нет) BOOT_STRUCTURE ends .data output_name db 'free.dat',0 ;имя файла first_string db 'Номера свободных кластеров диска A:',0dh,0ah ;заголовок в файле len_first_string equ $-first_string ;длина заголовка .data? boot db 512 dup (?) ;буфер для приема бутовой записи (и для вывода в файл) fat label byte ;начиная с этого адреса запишем все сектора FAT-а .code .startup lea bx, boot ;прочитаем бутовую запись mov cx, 1 ;0 дорожка, 1-й сектор mov dx, 0 ;0 головка, первый флоп mov ax, 0201h ;читаем один сектор int 13h mov si, bx ;будем адресовать бутовую запись через si ;число секторов одного FAT-а mov cx, [BOOT_STRUCTURE ptr si].FAT_size ;адрес буфера для FAT-а lea bx, fat ;определим первый сектор первого FAT-а ;будем хранить в di номер считываемого сектора + дорожка (в формате регистра cx) mov di, 2 ;1-й - boot, ищем, начиная со 2-го ;а вдруг есть невидимые (на флоппи их обычно нет) add di, [BOOT_STRUCTURE ptr si].Hidden_Sectors xor dx, dx ;0 головка, первый флоп sectors_loop: push cx mov cx,di ;зададим сектор+дорожку mov ax,0201h;читаем один сектор int 13h inc di ;инкремент номера сектора ;проверим, дошли ли до края дорожки? cmp di, [BOOT_STRUCTURE ptr si].Track_Sectors jbe next ;все ок, на следующий сектор ;переходим на другую головку mov di, 1 ;с первого сектора inc dh ;увеличиваем номер головки ;проверим, прошли ли все головки? cmp dh, byte ptr [BOOT_STRUCTURE ptr si].Heads_Count jb next ;переходим на следующий цилиндр (дорожку) mov dh, 0 ;с 0-й дорожки add di, 100h;инкремент цилиндра next: add bx, 200h;адрес буфера для следующего сектора pop cx loop sectors_loop ;по всем секторам ;Определим, сколько у нас есть кластеров ;Сначала посчитаем, сколько секторов использовано mov di, 2 ;начинаем со второго (первый - Boot) add di, [BOOT_STRUCTURE ptr si].Hidden_Sectors ;невидимые xor ax, ax mov al, [BOOT_STRUCTURE ptr si].FAT_Count ;количество FAT-ов mul [BOOT_STRUCTURE ptr si].FAT_size ;размер всех FAT-ов add di, ax ;накапливаем mov ax, [BOOT_STRUCTURE ptr si].Root_Size ;размер Root-а в записях shr ax, 4 ;всего в одном секторе 16 записей - делим на 16 add di, ax ;накапливаем mov ax, [BOOT_STRUCTURE ptr si].Total_Sectors;общее число секторов sub ax, di ;отнимем использованные mov cl, [BOOT_STRUCTURE ptr si].Cluster_Size;число секторов в кластере dec cl shr ax, cl ;ax = числу кластеров dec ax ;отнимем 1, т.к. первого нет, счет идет с 2 ;просмотрим считанную FAT и найдем все свободные кластера mov cx, ax ;счетчик кластеров mov bp, bx ;где закончили писать сектора FAT-а - буфер для номеров ; свободных кластеров xor di, di ;индекс в буфере свободных кластеров mov si, 2 ;в si - номер очередного кластера lea bx, fat+3 ;пропустим первые 3 байта search_free_loop: mov ax, [bx] ;"четный" номер and ax, 0fffh ;выделяем его jnz next_odd ;не 0 - занят mov [bp+di], si ;0 - свободен - сохраняем его номер add di, 2 ;для следующего next_odd: inc si ;номер следующего кластера loop cmp_odd ;циклим по cx jmp output_data ;если пройдем по всем, то на формирование файла cmp_odd: mov ax, [bx+1] ;"нечетный" номер shr ax, 4 ;выделяем его jnz next_both ;не 0 - занят mov [bp+di], si ;0 - свободен - сохраняем его номер add di, 2 next_both: inc si add bx, 3 ;на следующую пару loop search_free_loop output_data: ;сформируем файл с информацией lea dx, output_name ;создадим файл mov ah, 3ch mov cx, 0 int 21h mov bx, ax ;handle файла lea dx, first_string ;выведем заголовок mov cx, len_first_string mov ah, 40h int 21h mov si, bp ;адрес буфера номеров mov cx, di ;конечный использованный адрес shr cx, 1 ;число слов new_row: xor bp, bp ;будем выводить по 16 значений в строке, ; bp - счетчик в строке lea di, boot ;адрес буфера для формирования очередной строки row_loop: push cx lodsw ;читаем очередное слово call PrintWordHex ;сформируем в буфере hex-строку inc bp ;считаем число величин в строке cmp bp, 16 ;16 - максимум jb output_next ;меньше - добавим запятую и пробел mov ax, 0a0dh ;иначе - добавим перевод строки stosw mov cx, di ;адрес, куда дописали lea dx, boot ;адрес буфера sub cx, dx ;длина mov ah, 40h ;и выведем int 21h pop cx loop new_row ;на новую строку jmp close_file ;попадем сюда, если будут ровно по 16 output_next: mov ax, ' ,' ;разделим величины stosw pop cx loop row_loop ;на следующее значение cmp di, offset boot ;проверим, если есть незаконченная строка jne close_file mov word ptr [di-2],0a0dh ;закроем ее mov cx, di ;и выведем lea dx, boot sub cx, dx mov ah, 40h int 21h close_file: mov ah, 3eh ;закроем файл int 21h .exit 0 ;выход в ДОС PrintWordHex proc ;слово в hex push ax ;сохраним al в стеке mov al,ah ;выведем старший байт call PrintByteHex pop ax ;восстановим младший PrintByteHex proc ;выводим байт в hex push ax ;сохраним младшую тетраду shr al,4 ;старшая тетрада 00-0f call PrintHexDigit ;выводим hex цифру pop ax ;восстановим младшую тетраду and al,0fh ;выделим PrintHexDigit proc ;выводим hex цифру add al,90h ;последующие 4 команды преобразовывают daa ;число 00-0f в символы '0'-'9','A'-'F' adc al,040h daa stosb ret PrintHexDigit endp PrintByteHex endp PrintWordHex endp ret end
