здравствуйте. Есть задача: вывести в файл имена и последовательности кластеров для всех com и exe файлов корневого каталога диска A:. Пока работал с отладчиком (td.exe), проблем не было: все читалось, писАлось и отображалось. Когда окончательно отладил и стал запускать без отладчика, программа либо не выводит в файл вообще ничего, либо ведет себя так, будто не может считать часть секторов с дискеты. Здесь, видимо, какая-то тонкость есть, вот только никак не возьму в толк, в чем именно дело. При запуски из-под отладчика программа по-прежнему работает корректно... Подскажите, пожалуйста, кто-нибудь, что здесь не так: Код (Text): cseg segment ;привяжем сегмент к регистрам assume cs:cseg,ds:cseg,es:cseg,ss:cseg org 100h start: jmp begin ;объявим переменные handler dw 0h fname db 'a:\file.txt',0 fout db '----name----',': ',20h klaster db 'fff ' buf db 03000h dup(0) lister proc mov bp,sp mov bx,[bp+2] mov ax,word ptr [bx] ; v ax - nomer sled. klastera begina: xor dx,dx mov cx,02h div cx push dx mov cx,03h mul cx pop dx cmp dx,00h jne part2 part1: mov si,ax add si,offset buf add si,200h mov ch,[si]+1 mov cl,[si] and ch,0fh jmp pos part2: mov si,ax add si,offset buf add si,200h mov ch,[si]+2 mov cl,[si]+1 shr cx,04h and cx,0fffh pos: cmp cx,0fffh je finita ; v cx - soderjimoe tekuschego klastera mov [klaster],20h mov al,cl and al,0fh add al,30h cmp al,39h jle dd0 add al,07h dd0: mov [klaster]+3,al mov al,cl and al,0f0h shr al,4h add al,30h cmp al,39h jle dd1 add al,07h dd1: mov [klaster]+2,al mov al,ch and al,0fh add al,30h cmp al,39h jle dd2 add al,07h dd2: mov [klaster]+1,al push cx mov ah,40h mov bx,handler mov cx,04h mov dx,offset klaster int 21h pop ax jmp begina finita: mov [klaster],13 mov [klaster+1],10 mov ah,40h mov bx,handler mov cx,02h mov dx,offset klaster int 21h ret 2 lister endp print proc mov bp,sp ; vivod imeni i tipa faila mov cx,08h mov si,offset fout rt: mov al,[bx] mov [si],al inc si inc bx loop rt mov cx,03h mov al,2eh mov [si],al inc si rt2: mov al,[bx] mov [si],al inc si inc bx loop rt2 push bx mov ah,40h mov bx,handler mov cx,0fh mov dx,offset fout int 21h ; vivod spiska klasterov pop bx add bx,0fh mov al,[bx] and al,0fh add al,30h cmp al,39h jle ccc add al,07h ccc: mov [klaster]+2,al mov al,[bx] and al,0f0h shr al,04h add al,30h cmp al,39h jle ccc2 add al,07h ccc2: mov [klaster]+1,al mov al,[bx]+1 and al,0fh add al,30h cmp al,39h jle ccc3 add al,07h ccc3: mov [klaster],al mov [klaster]+3,20h push bx mov ah,40h mov bx,handler mov cx,04h mov dx,offset klaster int 21h mov ah,[bx+1] and ah,0fh call lister ret print endp begin: ; открытие файла сохранение handler mov ah,3ch mov cx,0h mov dx,offset fname int 21h mov handler,ax ;чтение секторов диска mov ah,02h mov al,0ah ;количество секторов mov ch,00h ;номер дорожки mov cl,01h ;номер сектора lea bx,buf ;адрес буфера mov dh,0 ;сторона 00 mov dl,0 ;дисковод 00 -> A: int 13h mov ah,02h mov al,0Eh ;количество секторов mov ch,00h ;номер дорожки mov cl,02h ;номер сектора lea bx,buf+1400h ;адрес буфера mov dh,01h ;сторона 01 mov dl,0 ;дисковод 00 -> A: int 13h ;zanesenie v bx adresa kornevogo kataloga lea bx,buf add bx,1400h big_c: mov al,[bx] cmp al,00h je endd cmp al,0e5h je endd exe: mov al,[bx]+8 cmp al,65h jne com mov al,[bx]+9 cmp al,78h jne com mov al,[bx]+0ah cmp al,65h jne com jmp printer com: mov al,[bx]+8 cmp al,63h jne EXE_SH mov al,[bx]+9 cmp al,6fh jne EXE_SH mov al,[bx]+0ah cmp al,6dh jne EXE_SH jmp printer EXE_SH: mov al,[bx]+8 cmp al,45h jne COM_SH mov al,[bx]+9 cmp al,58h jne COM_SH mov al,[bx]+0ah cmp al,45h jne COM_SH jmp printer COM_SH: mov al,[bx]+8 cmp al,43h jne endd mov al,[bx]+9 cmp al,4fh jne endd mov al,[bx]+0ah cmp al,4dh jne endd printer:push bx call print pop bx endd: add bx,20h lea dx,buf add dx,2600h add dx,1c00h cmp bx,dx jne big_c ; закрытие файла mov ah,3eh mov bx,handler int 21h mov ah,4ch int 21h cseg ends end start
Дискетка просто не успевает раскрутиться от 0 до нужной скорости. В старых доках рекомендуется первое чтение сектора выполнять не менее 3 раз, контролируя ошибку.
спасибо, drmad. помогли локализовать проблему, сделал так: Код (Text): metka: .... считывание секторов ... cmp ax, <число секторов, которое должно было считаться> jne metka Зацикливается! не может прочитать и все тут. При этом в отладчике программа по-прежнему работает как часы, даже в режиме безостановочного прогона. Как же все-таки заставить его прочитать секторы?
1. Один из секторов может быть битым. В этом случае (под чистым ДОСом) он прочитается с мусором внутри, а функа даст ошибку. 2. А заполняются ли ли все регистры в цикле заново? Лет 15 назад я делал примерно так: Код (Text): mov si, 4 metka: dec si jz error ; Сброс mov ah, 0 mov dl, 0 int 13h ; Чтение mov ah,02h mov al,0ah ;количество секторов mov ch,00h ;номер дорожки mov cl,01h ;номер сектора lea bx,buf ;адрес буфера mov dh,0 ;сторона 00 mov dl,0 ;дисковод 00 -> A: int 13h jc Metka ok: .... error: add byte ptr messag, ah mov ah, 9 lea dx, messag int 21h ... messag db 'a$' Если ошибка, то на экран выскакивала какая-то буква, по котрой легко можно было вычислить код ошибки. Если 'a' - нет ошибки, если 'b' - недопустимая команда; 'c' - неформатированная дорожка; 'i' - буфер под данные пересекает границы сегмента, и т.п. 3. Кстати, "буфер под данные пересекает границы сегмента" - тоже случается. А под дебагером может и не быть.