Доброго времени суток! У меня тут заданьеце : вывести атрибуты файла, в диалоговой форме произвести переустановку атрибутов. Реализовал первую часть - вывод атрибутов, использую функцию 43h прерывания 21h. Но возникает какая-то ошибка при вызове прерывания. В чём проблема?
data segment path db "E:\data.txt",0 mes1 db 13,10,"read\write$" mes2 db 13,10,"read only$" mes3 db 13,10,"X-files$" mes4 db 13,10,"system$" data ends
p.s. А как в far manager'е можно посмотреть атрибуты?
volvo
17.02.2009 0:43
Цитата
А как в far manager'е можно посмотреть атрибуты?
Ctrl+A...
Программу сейчас гляну...
volvo
17.02.2009 1:25
Так... А в программе-то у тебя ошибка в том, что ты сравниваешь значения, а надо проверять биты, маску то есть... Вот так, например (не стал ничего оптимизировать, чтоб был понятен принцип):
data segment path db 'F:/a.txt',0 mes1 db 13,10,'RO$' mes2 db 13,10,'Hidden$' mes3 db 13,10,'System$' mes4 db 13,10,'Label$' mes5 db 13,10,'Dir$' mes6 db 13,10,'Archive$' data ends
code segment assume cs: code, ds: data start: mov ax, data mov ds, ax
mov ah, 43h mov al,0 mov dx, offset path int 21h jc error_occured ; если CF = 1, значит ошибка
m1: mov ax, cx and ax, 0001h jz m2 mov ah, 09h mov dx, offset mes1 int 21h m2: mov ax, cx and ax, 0002h jz m3 mov ah, 09h mov dx,offset mes2 int 21h m3: mov ax, cx and ax, 0004h jz m4 mov ah, 09h mov dx,offset mes3 int 21h m4: mov ax, cx and ax, 0008h jz m5 mov ah, 09h mov dx,offset mes4 int 21h m5: mov ax, cx and ax, 0010h jz m6 mov ah, 09h mov dx,offset mes5 int 21h m6: mov ax, cx and ax, 0020h jz mx mov ah, 09h mov dx,offset mes6 int 21h jmp mx
error_occured: add ax, '0' int 29h
mx: mov ax, 4c00h int 21h code ends end start
Rocket
18.02.2009 2:09
Так, исправил следующем образом:
data segment path db "E:/data.txt",0 mes db 13,10,"R/W$" mes1 db 13,10,"RO$" mes2 db 13,10,"Hidden$" mes3 db 13,10,"System$" mes4 db 13,10,"Label$" mes5 db 13,10,"Dir$" mes6 db 13,10,"Archive$" data ends
m: mov ax,cx and ax,0000h jz m1 mov ah, 09h mov dx,offset mes int 21h
m1: mov ax,cx and ax,0001h jz m2 mov ah, 09h mov dx,offset mes1 int 21h
m2: mov ax,cx and ax,0002h jz m3 mov ah, 09h mov dx,offset mes2 int 21h
m3: mov ax,cx and ax,0004h jz m4 mov ah, 09h mov dx,offset mes3 int 21h
m4: mov ax,cx and ax,0008h jz m5 mov ah, 09h mov dx,offset mes4 int 21h
m5: mov ax,cx and ax,0010h jz m6 mov ah, 09h mov dx,offset mes5 int 21h
m6: mov ax,cx and ax,0020h jz mx mov ah, 09h mov dx,offset mes6 int 21h
jmp mx
error: add ax,'0' int 29h
mx: mov ax, 4c00h int 21h
code ends end start
Добавил проверку на атрибут "читать и записывать файл без ограничения", то есть 00h, но программа его игнорирует...почему?
volvo
18.02.2009 2:12
Где ты выкопал этот 00h, не расскажешь? Документация DOS знает только те маски, которые я тебе показал. Не надо ничего выдумывать... С точки зрения DOS 00h означает отсутствие каких-либо атрибутов.
Rocket
18.02.2009 2:15
Цитата(volvo @ 17.02.2009 22:12)
Где ты выкопал этот 00h, не расскажешь? Документация DOS знает только те маски, которые я тебе показал. Не надо ничего выдумывать...
мм...тогда сорри, просто в методичке, в которой изложено данное задание, приведён ещё и этот атрибут... Так сейчас буду практиковаться в изменении атрибутов
volvo
18.02.2009 2:16
P.S.
and ax,0000h jz m1
ты на самом деле надеешься, что после AND с 0000h когда-нибудь будет ненулевой результат??? CMP или TEST использовать не пробовал?
Rocket
18.02.2009 2:27
Цитата(volvo @ 17.02.2009 22:16)
P.S.
and ax,0000h jz m1
ты на самом деле надеешься, что после AND с 0000h когда-нибудь будет ненулевой результат??? CMP или TEST использовать не пробовал?
даа...прошляпил этот момент...
Rocket
18.02.2009 3:53
Вот пытаюсь произвести установку атрибута "read only":
data segment path db "E:/data.txt",0 mes db 13,10,"R/W$" mes1 db 13,10,"RO$" mes2 db 13,10,"Hidden$" mes3 db 13,10,"System$" mes4 db 13,10,"Label$" mes5 db 13,10,"Dir$" mes6 db 13,10,"Archive$" data ends
code segment assume cs:code, ds:data
showAtr proc
m : mov ax,cx cmp ax,0000h jnz m1 mov ah, 09h mov dx,offset mes int 21h
m1: mov ax,cx and ax,0001h jz m2 mov ah, 09h mov dx,offset mes1 int 21h
m2: mov ax,cx and ax,0002h jz m3 mov ah, 09h mov dx,offset mes2 int 21h
m3: mov ax,cx and ax,0004h jz m4 mov ah, 09h mov dx,offset mes3 int 21h
m4: mov ax,cx and ax,0008h jz m5 mov ah, 09h mov dx,offset mes4 int 21h
m5: mov ax,cx and ax,0010h jz m6 mov ah, 09h mov dx,offset mes5 int 21h
m6: mov ax,cx and ax,0020h jz mx mov ah, 09h mov dx,offset mes6 int 21h ret showAtr endp
Процедура showAtr вызывается только один - при первом вызове... и при изменении атрибута, все остальные сбрасываются... p.s. Данной функцией производится как установка, так и сброс атрибутов?
volvo
18.02.2009 5:10
Цитата
Данной функцией производится как установка, так и сброс атрибутов?
Естественно, ты устанавливаешь комбинацию атрибутов, задавая ее содержимым CX... Нулевые биты сбрасываются, единичные - выставляются... Если ты хочешь именно добавить атрибут - то
Естественно, ты устанавливаешь комбинацию атрибутов, задавая ее содержимым CX... Нулевые биты сбрасываются, единичные - выставляются... Если ты хочешь именно добавить атрибут - то
mov ax, 0001h ; Будем сбрасывать RO NOT AX AND CX, AX ; Вот теперь все биты остались прежними, кроме RO
mov ah, 43h mov al,1 ; и устанавливаешь int 21h
Rocket
20.02.2009 3:55
Теперь мне нужно сделать, чтоб всё это работало в диалоговой форме. Как сделать, чтоб при нажатии соответствующей кнопки, устанавливался/сбрасывался атрибут? то есть своеобразный case организовать... а вот проверку установить\сбросить атрибут опять же через and + условие jz ? Вот зачатки всего этого (меню пока что)
data segment path db "E:/data.txt",0 mes db 13,10,"R/W$" mes1 db 13,10,"RO$" mes2 db 13,10,"Hidden$" mes3 db 13,10,"System$" mes4 db 13,10,"Label$" mes5 db 13,10,"Dir$" mes6 db 13,10,"Archive$"
mesmen db 13,10,"ON\OFF RO pressed (1)",13,10,"ON\OFF Hidden pressed (2)",13,10,"ON\OFF System pressed (3)",13,10,"ON\OFF Label pressed (4)",13,10,"ON\OFF Dir pressed (5)",13,10,"ON\OFF Archive pressed (6)$"
data ends
code segment assume cs:code, ds:data
showAtr proc
m : mov ax,cx cmp ax,0000h jnz m1 mov ah, 09h mov dx,offset mes int 21h
m1: mov ax,cx and ax,0001h jz m2 mov ah, 09h mov dx,offset mes1 int 21h
m2: mov ax,cx and ax,0002h jz m3 mov ah, 09h mov dx,offset mes2 int 21h
m3: mov ax,cx and ax,0004h jz m4 mov ah, 09h mov dx,offset mes3 int 21h
m4: mov ax,cx and ax,0008h jz m5 mov ah, 09h mov dx,offset mes4 int 21h
m5: mov ax,cx and ax,0010h jz m6 mov ah, 09h mov dx,offset mes5 int 21h
m6: mov ax,cx and ax,0020h jz m7 mov ah, 09h mov dx,offset mes6 int 21h m7: ret
showAtr endp
start: mov ax,data mov ds,ax
mov ah, 09h mov dx,offset mesmen int 21h
mov ah, 43h mov al,0 mov dx, offset path int 21h
jc error
call showAtr
or cx,0008h
call showAtr
mov ax,0001h not ax and cx,ax
mov ah, 43h mov al,1 mov dx, offset path int 21h
jc error
call showAtr
jmp mx
error: add ax,'0' int 29h
mx: mov ax, 4c00h int 21h
code ends end start
volvo
20.02.2009 4:45
Цитата
Как сделать, чтоб при нажатии соответствующей кнопки, устанавливался/сбрасывался атрибут?
На самом деле все просто:
; вывел меню
; получил текущие атрибуты файла mov ah, 43h mov al, 0 mov dx, offset path int 21h jc error
; вывел атрибуты call showAtr ; запомнил, оно дальше пригодится... ; естественно, в сегменте данных не забудь описать myAttr DW ? mov myAttr, cx
; ждешь нажатия на кнопку mov ah, 01h int 21h ; получаешь НОМЕР кнопки - 1 sub al, '0' dec al
; это будет сдвиг mov cl, al mov ax, 0001h ; получаем маску для выбранного пользователем бита shl ax, cl ; восстанавливаем атрибуты в CX mov cx, myAttr and cx, ax ; нужный бит установлен ? jz not_set ; Да, был установлен, надо его сбросить mov cx, myAttr not ax and cx, ax jmp set_attr not_set: ; Нет, результат AND был 0, значит, бит не был установлен mov cx, myAttr or cx, ax
set_attr: ; и устанавливаем то, что вышло... mov ah, 43h mov al,1 mov dx, offset path int 21h jc error call showAtr jmp mx ; ...
, я здесь не делал никаких проверок на то, какие клавиши нажимались... Добавь там проверку, после чтения с клавиатуры, что нажата одна из кнопок '1' .. '6', чтоб не было никаких неожиданностей...
Rocket
20.02.2009 23:24
Вот, что у меня получилось:
data segment path db "E:/data.txt",0 mes db 13,10,"R/W$" mes1 db 13,10,"RO$" mes2 db 13,10,"Hidden$" mes3 db 13,10,"System$" mes4 db 13,10,"Label$" mes5 db 13,10,"Dir$" mes6 db 13,10,"Archive$"
mesmen db 13,10,"ON\OFF RO pressed (1)",13,10,"ON\OFF Hidden pressed (2)",13,10,"ON\OFF System pressed (3)",13,10,"ON\OFF Label pressed (4)",13,10,"ON\OFF Dir pressed (5)",13,10,"ON\OFF Archive pressed (6)$"
mes_error_1 db 13,10,"Illegal button!$"
myAttr DW ?
data ends
code segment assume cs:code, ds:data
showAtr proc
m : mov ax,cx cmp ax,0000h jnz m1 mov ah, 09h mov dx,offset mes int 21h
m1: mov ax,cx and ax,0001h jz m2 mov ah, 09h mov dx,offset mes1 int 21h
m2: mov ax,cx and ax,0002h jz m3 mov ah, 09h mov dx,offset mes2 int 21h
m3: mov ax,cx and ax,0004h jz m4 mov ah, 09h mov dx,offset mes3 int 21h
m4: mov ax,cx and ax,0008h jz m5 mov ah, 09h mov dx,offset mes4 int 21h
m5: mov ax,cx and ax,0010h jz m6 mov ah, 09h mov dx,offset mes5 int 21h
m6: mov ax,cx and ax,0020h jz m7 mov ah, 09h mov dx,offset mes6 int 21h m7: ret
showAtr endp
start: mov ax,data mov ds,ax
mov ah, 43h mov al,0 mov dx, offset path int 21h
jnc m_
add ax,'0' int 29h jmp mx
m_: call showAtr
xor ax,ax mov ah, 09h mov dx,offset mesmen int 21h
mov ah,01h int 21h
sub al,'0' dec al
mov ah,al sub ah,1 jz m_1
mov ah,al sub ah,2 jz m_2
mov ah,al sub ah,3 jz m_3
mov ah,al sub ah,4 jz m_4
mov ah,al sub ah,5 jz m_5
mov ah,al sub ah,6 jz m_6
mov ah, 09h mov dx,offset mes_error_1 int 21h jmp mx
...а скорей не получилось : при нажатии клавиши возникает ошибка и работа программы прекращается. Я сделал без вот этого момента :
; это будет сдвиг mov cl, al mov ax, 0001h ; получаем маску для выбранного пользователем бита shl ax, cl
- не особо понял, что здесь происходит.
volvo
21.02.2009 0:36
Цитата
Я сделал без вот этого момента :
А что ж ты сделал тогда? Что за привычка - ВЫБРОСИТЬ все, что не понял, а потом сказать, что программа не работает?
Как ты хочешь менять значение определенного атрибута на противоположное? Чтобы это сделать, надо дождаться от пользователя решения, какой атрибут менять, потом перейти к соответствующему биту (для атрибута RO - это нулевой, самый младший бит, LSB как говорится; для атрибута Hidden - первый, для System - второй, и т.д.), проверить его текущее состояние, если он сейчас установлен, то сбросить, если НЕ установлен - установить. Так?
Продолжаем.. Как проверить бит, соответствующий данному атрибуту? Для начала, надо получить номер бита, начиная с 0. Получили, что дальше? Создаем маску для нужного бита: значение 0001h надо сдвинуть влево на столько, какой бит мы проверяем. Вот это и делается в нижеследующих строках:
mov cl, al ; Не забыл, в AL у тебя номер бита, который надо поменять ... mov ax, 0001h ; то самое значение 0001h ; получаем маску для выбранного пользователем бита shl ax, cl ; Сдвигаем 0001h...
Теперь у нас в AX - маска, с единицей ТОЧНО в том же месте, где находится изменяемый бит атрибута... Кстати, твою программу можно сократить значительно, ты бы макросы что-ли задействовал? У тебя ж одно и то же делается 6 раз подряд...
И вот этого я не говорил, ты сам это придумал:
Цитата
mov ah,al sub ah,1 jz m_1 mov ah,al sub ah,2 jz m_2 mov ah,al sub ah,3 jz m_3 mov ah,al sub ah,4 jz m_4 mov ah,al sub ah,5 jz m_5 mov ah,al sub ah,6 jz m_6
В общем, перечитывай еще раз мой предыдущий пост. Там кусок из ОТРАБОТАВШЕЙ программы. Понимаешь? Она работает, а не должна бы работать... Вот и разберись, как она работает...
Rocket
21.02.2009 3:17
Цитата(volvo @ 20.02.2009 20:36)
А что ж ты сделал тогда? Что за привычка - ВЫБРОСИТЬ все, что не понял, а потом сказать, что программа не работает?
Как ты хочешь менять значение определенного атрибута на противоположное? Чтобы это сделать, надо дождаться от пользователя решения, какой атрибут менять, потом перейти к соответствующему биту (для атрибута RO - это нулевой, самый младший бит, LSB как говорится; для атрибута Hidden - первый, для System - второй, и т.д.), проверить его текущее состояние, если он сейчас установлен, то сбросить, если НЕ установлен - установить. Так?
Продолжаем.. Как проверить бит, соответствующий данному атрибуту? Для начала, надо получить номер бита, начиная с 0. Получили, что дальше? Создаем маску для нужного бита: значение 0001h надо сдвинуть влево на столько, какой бит мы проверяем. Вот это и делается в нижеследующих строках:
mov cl, al ; Не забыл, в AL у тебя номер бита, который надо поменять ... mov ax, 0001h ; то самое значение 0001h ; получаем маску для выбранного пользователем бита shl ax, cl ; Сдвигаем 0001h...
Теперь у нас в AX - маска, с единицей ТОЧНО в том же месте, где находится изменяемый бит атрибута... Кстати, твою программу можно сократить значительно, ты бы макросы что-ли задействовал? У тебя ж одно и то же делается 6 раз подряд...
И вот этого я не говорил, ты сам это придумал: В общем, перечитывай еще раз мой предыдущий пост. Там кусок из ОТРАБОТАВШЕЙ программы. Понимаешь? Она работает, а не должна бы работать... Вот и разберись, как она работает...
Убрал порцию нездоровой отсебятины, перечитал ещё пару раз пост...и всё заработало наилучшим образом! Спасибо)
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.