Помощь - Поиск - Пользователи - Календарь
Полная версия: Fat
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер
Yurik
Приветы,люди!
Поможите кто шарит плиз.
Вообщем, дали задание написать прогу на Паскале, что бы выводила таблицу ФАТ винта - ничего ненашел в инете- собственно понятно что дело в ассемблерной вставке - но увы асм - вообще гол...подскажите кто знает.
Заранее благодарю
Dark
поищи по интернет запрос
FAT таблица
найди ее структуру - напиши обработчик
Будут вопросы - приходи
Я НАХОДИЛ
Altair
Дарк, посыл человека в гугл не есть хорошо!
Yurik, у нас на форуме я выкладывал уже кое какую информацию о FAT.
вот здесь

Сразу реши, программа будет на ассемблере или на паскале со вставками асма ?
Если второе то вот посотри сюда
Там автор приводит пример программы выводящей карту диска и какую-то информацию еще.
Dark
Ну =) если бы Yrik пришел с тем что "я пробовал но вот у меня не получилось" - я б помог НО если человек говорит что ему нужен вывод FAT - не могу поверить что он ударил пальцем о палец... Думаю многие модеры согласяться со мной... И еще - нечетко поставлена задача smile.gif у него нет просьбы чтоб я нашел либо выложил что нибудь... Гхм (пипипи) че то я с бессонницы философствую...
MixRin.RU$
Цитата(Dark @ 24.01.2006 10:40) *

Ну =) если бы Yrik пришел с тем что "я пробовал но вот у меня не получилось" - я б помог НО если человек говорит что ему нужен вывод FAT - не могу поверить что он ударил пальцем о палец... Думаю многие модеры согласяться со мной... И еще - нечетко поставлена задача smile.gif у него нет просьбы чтоб я нашел либо выложил что нибудь... Гхм (пипипи) че то я с бессонницы философствую...

не все умеют грамотно составлять запросы поисковикам и тем более вылавливать нужные ссылки среди всякого 'гумна'.
Dark
чес слово - шел шел по инету - и случайно нашел. FAT дискеты =)

; Чтение сектора (DX=номер сектора) ##########################################
; ES:DI - куда читать
PROC ReadSect
push di es
; Начало расчета сектора/дорожки/головки
push cs
pop ds
mov cx,18
mov si,dx
; tmp=(Sect/Sectors);
mov ax,si
xor dx,dx
div cx
mov di,ax
; Sec=Sect-(tmp*Sectors)+1;
mov ax,di
imul cx
mov dx,si
sub dx,ax
inc dx
mov [AbsSectNum],dx
; Hea=tmp & 1;
mov ax,di
and ax,1
mov [AbsHeadNum],ax
; Trk=(Sect-(Hea*Sectors)-(Sec-1))/(Sectors*2);
imul cx
push ax
mov ax,si
pop dx
sub ax,dx
mov dx,[AbsSectNum]
dec dx
sub ax,dx
mov dx,cx
shl dx,1
push ax
push dx
xor dx,dx
pop bx
pop ax
div bx ; AX = AbsTrackNum
; Конец расчетов
mov cx,ax
mov al,cl
shr cx,2
and cl,0C0h
mov ch,al
and cx,0FFC0h
mov ax,[AbsSectNum] ; г5T4T3T2T1T0T9T8T7T6T5T4T3T2T1T0¬
or cl,al ; CX = c c c c c c c c C c S s s s s s
pop es bx ; ES:BX = Куда считывать
mov dx,[AbsHeadNum]
mov dh,dl ; Номер головки
mov dl,0 ; Номер диска 0 = A
mov al,1 ; Количество считываемых секторов
mov ah,2 ; Номер функции
int 13h
ret
ENDP ReadSect
; Чтение сектора в стандартный буффер ########################################
RSSData DW 0
PROC CachedReadSector
cmp dx,[cs:RSSData]
je RSSEnd
mov [cs:RSSData],dx
push di si es ax bx cx dx
lea di,[sector]
push cs
pop es
call ReadSect
pop dx cx bx ax es si di
RSSEnd: ret
ENDP CachedReadSector
; Чтение FAT'а ###############################################################
PROC ReadFAT
push cs
pop es
mov dx,1
lea di,[FAT]
readfat1: push es dx di

Call ReadSect
pop di dx es
add di,512
inc dx
cmp dx,10
jne readfat1
ret
ENDP ReadFAT
; Выдает следующий сектор после DX (через FAT) ###############################
gns_flag DW 0
PROC GetNextSector
cmp dx,2
je gns03
cmp [Word Ptr cs:gns_flag],0
jne gns04
push cx di bx
lea di,[FAT]
mov ax,dx
mov bx,ax
mov cx,3
mul cx
shr ax,1
add di,ax
mov dx,[di]
and bx,1
je gns01 ; Если номер кластера четный
shr dx,4
jmp gns02
gns01: and dx,0FFFh
gns02: pop bx di cx
ret
gns03: mov dx,[RootSect]
ret
gns04: mov [Word Ptr cs:gns_flag],0
add dx,33-2
ret
ENDP GetNextSector
; Конвертит номер сектора в номер кластера ###################################
Sect2ClustRoot DW 0
PROC Sect2Clust
cmp dx,33
jb Sect2Clust1
sub dx,33-2
mov [Word Ptr cs:Sect2ClustRoot],0
ret
Sect2Clust1: mov [Word Ptr cs:Sect2ClustRoot],1
ret
ENDP Sect2Clust
; По строке (обычно командной) выдает номер сектора (DS:DI = строка ) ########
; Возвращает AX = номер превого сектора каталога
GetSectorName DB 13 DUP (0),0
GetSectorClust DW 0
Prohod DW 0
PROC GetSectorNum
call UpperString ; [DI] = D:\CAT1\CAT2\
mov al,[di] ; AL = Диск 'A'-'Z'
sub al,'A' ; AL = Диск 0 - 32
xor ax,ax
mov [Word Ptr cs:GetSectorClust],2
mov [Word Ptr cs:gns_flag],1
mov [cs:Prohod],ax
add di,3 ; [DI] = CAT1\CAT2\

nextsubdir: mov si,di
gsn003: mov al,[si]
or al,al
je gsn001
cmp al,'\'
je gsn001
inc si
jmp gsn003
gsn001: cmp di,si ; [DI] = CAT1\CAT2
je gsn002 ; [SI] = \CAT2
xor cx,cx
mov bx,si
push si
lea si,[GetSectorName]
gsn005: mov al,[di]
cmp al,'.' ; Если есть расширение
je gsn004
mov [cs:si],al
inc di
inc si
inc cx
cmp di,bx
jne gsn005
pop di
; Добьем имя нулями
gsn006: mov [Byte Ptr cs:si],20h
inc cx
inc si
cmp cx,11
jne gsn006
jmp gsn007
gsn002: mov ax,[cs:Prohod]
or ax,ax
jne gsn0021
mov ax,[Root] ; Корень
jmp gsn0022
gsn0021: mov ax,[GetSectorClust]
gsn0022: ret
gsn004: cmp cx,8
je gsn008
mov [Byte Ptr cs:si],20h
inc cx
inc si
jmp gsn004
gsn008: inc di
inc cx
cmp cx,12
je gsn010
mov al,[di]
or al,al
je gsn009
mov [cs:si],al
inc si
jmp gsn008
gsn009: pop di
jmp gsn006
gsn010: pop dx
gsn007: push di

; Ищем в корне запрошеный каталог (CAT1)
mov dx,[GetSectorClust]
lea di,[sector]
gsn13: call GetNextSector
cmp dx,0FFFh
je gsn14
push dx
call CachedReadSector
mov [Word Ptr cs:gns_flag],0
lea di,[sector]
lea si,[GetSectorName]
mov cx,16 ; 16 - количество записей в одном секторе
gsn12: push di si cx
call CmpStrings
pop cx si di
jc gsn11
notdir: add di,32
dec cx
jne gsn12
pop dx
jmp gsn13
gsn14: pop di ; Не найдено не фига
xor ax,ax
ret
gsn11: ; Найдена запись - сравним аттрибуты
mov al,[di+11]
and al,10h
je notdir ; Это не каталог
mov ax,[di+01Ah]
mov [GetSectorClust],ax
pop dx di
inc di
mov [Word cs:Prohod],1
mov [Word Ptr cs:gns_flag],1
jmp nextsubdir
ENDP GetSectorNum
; FindFirst ##################################################################
; Возвращает: AX=0=Ok; AX=1=Patch not found
PROC FindFirst
; Читаем FAT
push cs
pop ds
; Узнаем номер сектора, где начинается корень
lea di,[dos_CurDir]
call GetSectorNum ; В AX - номер кластера с каталогом
or ax,ax
je ff03
mov dx,ax
mov [Word Ptr cs:gns_flag],1
push cs
pop es
call GetNextSector
ff02: push dx
call CachedReadSector
pop dx
; Копируем первую запись в каталоге в структуру _dos
lea si,[sector]
mov cx,16
ff01: mov al,[si]
or al,al ; 0 - пустая запись каталога
je nofile
cmp al,'х' ; 'x' - удаленая запись
je nofile
mov ax,[si+11]
cmp ax,0Fh ; Если это LFN
je nofile
lea di,[dos_FileName]
mov bx,cx
mov cx,32
rep movsb
jmp ff_makefind
nofile: add si,32
dec cx
or cx,cx
jne ff01
cmp dx,32
jna nofile1
call GetNextSector
jmp ff02
nofile1: inc dx
jmp ff02
ff_makefind: ; Копируем содержимое структуры dos_ в структуру _find
lea si,[dos_FileName]
lea di,[find_FileName]
mov cx,32
rep movsb
mov ax,16
sub ax,bx
mov [di],dx
mov [di+2],ax
xor ax,ax
ret
ff03: mov ax,1
ret
ENDP FindFirst
; Ищет следующий файл в каталоге #############################################
; Возвращает: AX=0=Ok; AX=1=Patch not found
PROC FindNext
lea si,[find_FileName]
mov dx,[si+32] ; DX - номер сектора
mov ax,[si+34]
fnNextSector0: cmp ax,15 ; Надо читать следующий
je fnNextSector1
mov [Word Ptr cs:gns_flag],1
fnNextSector: push cs
pop es
push ax
call Sect2Clust ; DX - номер кластера
cmp [Word Ptr cs:Sect2ClustRoot],0
jne fnNextSector5 ; Если корень
call GetNextSector
cmp dx,0FFFh
je fnNextSector2
fnNextSector4: push dx
call CachedReadSector
pop dx ax ; Нужный сектор считан
inc ax ; AX - номер записи (0..15)
push ax
shl ax,5 ; AX=AX*5
lea si,[sector]
add si,ax

; Проверим на пустую запись, удаление и LFN
mov bl,[si]
or bl,bl ; 0 - пустая запись каталога
je fn_nofile
cmp bl,'х' ; 'x' - удаленая запись
je fn_nofile
mov bx,[si+11]
cmp bx,0Fh ; Если это LFN
je fn_nofile

lea di,[dos_FileName]
mov cx,32
rep movsb
pop ax
lea si,[dos_FileName]
lea di,[find_FileName]
mov cx,32
rep movsb
mov [di],dx
mov [di+2],ax
xor ax,ax
ret
fn_nofile: pop ax
jmp fnNextSector0
fnNextSector2: pop ax
mov ax,1
ret
fnNextSector1: xor ax,ax
dec ax
jmp fnNextSector
fnNextSector5: cmp [Word Ptr cs:gns_flag],1
je fnNextSector51
inc dx
cmp dx,33
je fnNextSector2
fnNextSector51: mov [Word Ptr cs:gns_flag],0
jmp fnNextSector4
ENDP FindNext


P.S. работоспособность не поверял
P.S.S. Интересно - а автору темы это надо еще?
Yurik
Привет! Сорри, что не отвечал - не работал инет. Спасибо всем кто откликнулся - пальцем об палец бью уже который день - но увы...кстати у меня тоже есть пример программы считки ФАТа дискеты, но! - программа просто находит где ни диискете БУТ, где ФАТ - просто откликаеться на номер введенного сектора - мол что это есть дата, бут, фат... поменял я в этой проге регистр, где указываеться номер диска по счету начиная с А -тобишь А, Б, Ц,Д - то есть мне нужен Ц - 2 получаецца - запускаю - нифига - прога нагло вылетает и ИксПи пишет, что было обращение к винту и все такое...короче то ли Икс Пи не разрешает, то ли я че то нахимичил... unsure.gif ДА! Кстати совсем забыл - задание у меня было : РАСШИФРОВАТЬ ФАТ! - больше ничего не написано blum.gif А разве он зашифрован? Разве есть алгоритм шифрования? Разве нужен ключ... unsure.gif .Вообщем беда еще и в том что уточнить задание не имею возможности - так как учусь на заочном - кто учился, тот поймет...Вылаживаю код программа, о которой говорил выше -

_______________________________________________________________________

Program Inf_Boot;
Uses Crt, Dos;
Type
TBoot = Record
JMPxx : Array [1..3] Of Byte;
OEMname : Array [1..8] Of Char;
SectSiz : Word;
ClustSiz : Byte;
ResSecs : Word;
FatCnt : Byte;
RootSiz,
TotSecs : Word;
Media : Byte;
FatSize,
TrkSecs,
HeadCnt : Word;
HidnSec,
BigSectNumb : LongInt;
DevNum,
res1,
Sygnatura : Byte;
DiskSerialNum : LongInt;
DiskVolume : Array [1..11] Of Char;
FileSystemID : Array [1..8] Of Char;
res2 : Array [1..512 - 62] Of Byte;
End;

Var
nBoot,nFAT,nRoot,nData,nMAX,Num : Word;
Boot : TBoot;


Procedure ReadBoot(Disk : Byte);
Var
SegRec,OfsRec,Error : Word;
Begin
SegRec := Seg(Boot);
OfsRec := Ofs(Boot);
Asm
mov AL,Disk
mov CX,1
mov DX,0
mov DS,SegRec
mov BX,OfsRec
int 25h
pop DX
mov Error,AX

End;
End;



Begin
Write('Enter a number of floppy disk (a=0,b=1): '); ReadLn(Num);
ReadBoot(Num);
nBoot := 0;
With Boot Do Begin
nFAT := nBoot + ResSecs;
nRoot := nFAT + FatSize * FatCnt;

nData := nRoot + (RootSiz * 32) Div SectSiz;
nMAX := TotSecs;
End;
Repeat
Write('Enter a number of sector: '); ReadLn(Num);
If Num In [nBoot..nFAT - 1]
Then WriteLn('Boot')
Else
If Num In [nFAT..nRoot - 1]
Then WriteLn('FAT')
Else
If Num In [nRoot..nData - 1]
Then WriteLn('Root')
Else
If Num In [nData..nMAX - 1]
Then WriteLn('Data')
Else WriteLn('Error');

Write('agan yes - 1, no - 0 :'); ReadLn(Num);
Until(Num = 0);
End.


Тегами пользуемся...
MixRin.RU$
Юрик, я думаю что WinXP просто блокирует обращение к винту, есть такое смутное сомнение, так что попробуй проверить на эмуляторе или чистом ДОС, стандартный виндовый эмуль (ntvdm) фигня имхо... По поводу 'расшифровать FAT' я думаю что надо просто сделать красивый вывод этой таблицы, то есть например:
	 FAT-таблица
---------------------
параметр#1|значение#1
параметр#2|значение#2
параметр#3|значение#3
...
параметр#n|значение#n
PS я сам не знаю формат этой таблицы, поэтому прошу за совет не ругать rolleyes.gif
Yurik
Короче манался я манался с этой прогой - много прошло через меня аналогичных, но! - не одна не захотела работать с ФАТ32. С дискетой-пожалуйста! с винтом - рантайм эррор с адресом того самого эррора! - забил и решал делать для ФАТ16 хоть... - !!! хотя вприципе и не было прог, которые бы тупо вылили раздел ФАТ - в виде даже билеберды на экран иль в файл - не суть важно. - Пробывал писать проги как написано в примерах в НГ и в Тече 6.0 , но при обработке формул то "деление на 0" выдает то еще что то...эх! нутром чую что проги не сложные, но чего то не хотять работать-еще не понятно в них смыл использовани сегмент:смещение - вроде как уже плоская модель используеться - возможно это служит в виде буфера результата обработки прерывания - туды вылазит ФАТ? ....фух.... mega_chok.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.