1. Заголовок или название темы должно быть информативным 2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE] 3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора. 5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM! 6. Проверяйте программы перед тем, как выложить их на форум!!
Доброго времени суток! У меня тут заданьеце : вывести атрибуты файла, в диалоговой форме произвести переустановку атрибутов. Реализовал первую часть - вывод атрибутов, использую функцию 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
Так... А в программе-то у тебя ошибка в том, что ты сравниваешь значения, а надо проверять биты, маску то есть... Вот так, например (не стал ничего оптимизировать, чтоб был понятен принцип):
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
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
Где ты выкопал этот 00h, не расскажешь? Документация DOS знает только те маски, которые я тебе показал. Не надо ничего выдумывать... С точки зрения DOS 00h означает отсутствие каких-либо атрибутов.
Где ты выкопал этот 00h, не расскажешь? Документация DOS знает только те маски, которые я тебе показал. Не надо ничего выдумывать...
мм...тогда сорри, просто в методичке, в которой изложено данное задание, приведён ещё и этот атрибут... Так сейчас буду практиковаться в изменении атрибутов
Вот пытаюсь произвести установку атрибута "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. Данной функцией производится как установка, так и сброс атрибутов?
Данной функцией производится как установка, так и сброс атрибутов?
Естественно, ты устанавливаешь комбинацию атрибутов, задавая ее содержимым CX... Нулевые биты сбрасываются, единичные - выставляются... Если ты хочешь именно добавить атрибут - то
Естественно, ты устанавливаешь комбинацию атрибутов, задавая ее содержимым CX... Нулевые биты сбрасываются, единичные - выставляются... Если ты хочешь именно добавить атрибут - то
Теперь мне нужно сделать, чтоб всё это работало в диалоговой форме. Как сделать, чтоб при нажатии соответствующей кнопки, устанавливался/сбрасывался атрибут? то есть своеобразный 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
Как сделать, чтоб при нажатии соответствующей кнопки, устанавливался/сбрасывался атрибут?
На самом деле все просто:
; вывел меню
; получил текущие атрибуты файла 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', чтоб не было никаких неожиданностей...
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
А что ж ты сделал тогда? Что за привычка - ВЫБРОСИТЬ все, что не понял, а потом сказать, что программа не работает?
Как ты хочешь менять значение определенного атрибута на противоположное? Чтобы это сделать, надо дождаться от пользователя решения, какой атрибут менять, потом перейти к соответствующему биту (для атрибута 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
В общем, перечитывай еще раз мой предыдущий пост. Там кусок из ОТРАБОТАВШЕЙ программы. Понимаешь? Она работает, а не должна бы работать... Вот и разберись, как она работает...
А что ж ты сделал тогда? Что за привычка - ВЫБРОСИТЬ все, что не понял, а потом сказать, что программа не работает?
Как ты хочешь менять значение определенного атрибута на противоположное? Чтобы это сделать, надо дождаться от пользователя решения, какой атрибут менять, потом перейти к соответствующему биту (для атрибута RO - это нулевой, самый младший бит, LSB как говорится; для атрибута Hidden - первый, для System - второй, и т.д.), проверить его текущее состояние, если он сейчас установлен, то сбросить, если НЕ установлен - установить. Так?
Продолжаем.. Как проверить бит, соответствующий данному атрибуту? Для начала, надо получить номер бита, начиная с 0. Получили, что дальше? Создаем маску для нужного бита: значение 0001h надо сдвинуть влево на столько, какой бит мы проверяем. Вот это и делается в нижеследующих строках:
mov cl, al ; Не забыл, в AL у тебя номер бита, который надо поменять ... mov ax, 0001h ; то самое значение 0001h ; получаем маску для выбранного пользователем бита shl ax, cl ; Сдвигаем 0001h...
Теперь у нас в AX - маска, с единицей ТОЧНО в том же месте, где находится изменяемый бит атрибута... Кстати, твою программу можно сократить значительно, ты бы макросы что-ли задействовал? У тебя ж одно и то же делается 6 раз подряд...
И вот этого я не говорил, ты сам это придумал: В общем, перечитывай еще раз мой предыдущий пост. Там кусок из ОТРАБОТАВШЕЙ программы. Понимаешь? Она работает, а не должна бы работать... Вот и разберись, как она работает...
Убрал порцию нездоровой отсебятины, перечитал ещё пару раз пост...и всё заработало наилучшим образом! Спасибо)