Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как определить диск?

367
19 июля 2006 года
Meatcoins
303 / / 18.01.2006
Как программе определить на каком она находится диске и полный путь до себя?

push cs
pop ds
......
disk:
db 0
db 0
db 0
dir:
dq 0
dq 0
......
dq 0
......
mov ax,4700h
xor dx,dx ;текущий диск!
mov si,offset dir ;сюда запишем полный путь без имени
int 21h ;диска и последнего символа '/'!

У меня есть вариант:
Вызывать эту функцию в цикле и инкрементировать dx до тех пор пока не исчезнет ошибка, а также сравнивать с первой итерацией. Так можно обнаружить диск, а затем дописать в начало имя в зависимости от полученного dx. Например, так:

mov di,offset disk
mov ax,0040h
add ax,dx
mov byte ptr ds:[di],al
mov ax,'\:'
mov byte ptr ds:[di+2],ax

А можно ли всё это сделать как-нибудь проще???
349
19 июля 2006 года
Phantom-84
656 / / 27.10.2005
Насколько я понял, тебя интересует, как это можно сделать в DOS. Смутно припоминаю, что полное имя исполняемого файла программы DOS помещает после персональной для программы копии Environment-блока.
367
20 июля 2006 года
Meatcoins
303 / / 18.01.2006
Программа должна определить на каком она диске находится и в какой папке! У меня есть предположение как это сделать, но оно мне кажется каким-то нерациональным, потому что скорее всего должна быть какая-то функция или что-то ещё, чтобы определить диск своего обитания!
Поясню ещё разок:
Ведь в 47h функции DOS при dx = 0 (текущий диск) определяется путь к текущей директории, т.е. путь к "себе", а при dx = 1, 2, 3... выбирается диск A, B, C... При dx = 0 и dx = n результаты должны совпасть! Так и определится текущий диск.
Теперь вопрос:
Есть ли способ проще? Скажем вызываю функцию DOS XXh и получаю номер или букву диска на котором "я" сижу?

RE:
Насколько я понял, тебя интересует, как это можно сделать в DOS.

Всё правильно - в DOS'е! Но ведь приложения DOS'а могут выполняться и Windows'е в консольном режиме!

RE:
Смутно припоминаю, что полное имя исполняемого файла программы DOS помещает после персональной для программы копии Environment-блока.

А тут я не понял. Что это за персональная копия Environment-блока? Это не PSP случайно ли?
Я не знаю что куда там DOS помещает, я полный путь к "себе" хочу получить с помощью функции DOS 47h!
367
20 июля 2006 года
Meatcoins
303 / / 18.01.2006
.model small
.stack 100h
.code
start:
push cs
pop ds
push ds
pop es
jmp above_dta
psevdo: db 0,0,0
my_dta:
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
disk:
db "e:\" ;На это можно не обращать внимания.
dir: ;Всёравно он переопределяется потом.
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
hehe:
dq 0
above_dta:
mov ax,1A00h
mov dx,offset my_dta
int 21h
mov ax,4700h
xor dx,dx
mov si,offset dir
int 21h
mov di,offset dir
xor dx,dx
mov ax,word ptr ds:[di]
cmp ax,dx
jne nextyy
call find_around
nextyy:
mov cx,0008h
inc dx
inc dx
define:
mov ax,4700h
inc dx
mov si,offset my_dta
int 21h
mov si,offset my_dta
mov di,offset dir
push cx
mov di,offset my_dta
xor dx,dx
mov ax,word ptr ds:[di]
cmp ax,dx
jne nextyyy
call find_around
nextyyy:
mov cx,0080h
repe cmpsb
pop cx
je enddefine
loop define
enddefine:
add dx,0060h
mov di,offset disk
mov byte ptr ds:[di],dl


;Всё работает, но если файл попадёт "чисто" на диск,
;скажем d:\me.exe,
;то он не поймёт на каком он диске!



jmp check


;А эта функция пытается сравнить окружающие файлы
;и если они одни
;и теже, то значит файл на этом диске.

find_around proc near
mov ax,1A00h
mov dx,offset local_dta
int 21h
jmp qwerty
qwe: db "*.*"
buf0: db 0
local_dta:
dq 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
buf11:
dq 0,0,0,0,0,0,0,0
buf22:
dq 0,0,0,0,0,0,0,0
qwerty:
mov di,offset buf0
mov al,byte ptr ds:[di]
cmp al,0
jne go_nexty
mov al,01h
mov byte ptr ds:[di],al

go_nexty:

xor cx,cx
go_nexty2:
mov ax,4E00h
mov dx,offset qwe
int 21h
jc qwe_end
jmp short gakar
qwe_next:
mov ax,4F00h
int 21h
jc qwe_end
gakar:
mov cx,0008h
mov si,???????????????????
jmp short qwe_next
buff0: db 0
qwe_end:
mov di,offset buff0
mov al,byte ptr ds:[di]
cmp al,0
jne go_nextyyy
mov cx,00010000b
jmp go_nexty2
go_nextyyy:
xor ax,ax
mov byte ptr ds:[di],al

mov ax,1A00h
mov dx,offset my_dta
int 21h
retn
find_around endp


check:

;jmp eeee

jmp short ttt
u: db "88.txt",0
ttt:
mov ax,3C00h
mov dx,offset u
xor cx,cx
int 21h
mov bx,ax
mov ax,4000h
mov dx,offset my_dta
mov cx,offset above_dta-offset my_dta
;mov dx,offset my_memory
;mov cx,offset endy-offset my_memory
int 21h
mov ax,3E00h
int 21h
eeee:
mov ax,0600h
mov dx,0007h
int 21h
mov ax,4C00h
int 21h
367
20 июля 2006 года
Meatcoins
303 / / 18.01.2006
Проще, но он мне не совсем нравится...
Можно ли как-нибудь без создавания дирректорий обойтись?
P.S.
На "худой конец" просто присваивается диск C, но это ерунда просто...

Недостаток в том, что если директория уже создана, то ничего не получается и присваивается диск C. И ещё: не получатся сменить директорию с помощью функции DOS 3Bh, чтобы текущая директория стала на другом диске!



.model small
.stack 100h
.code
start:
push cs
pop ds
push ds
pop es
jmp above_dta
psevdo: db 0,0,0
my_dta:
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
disk:
db 0,0,0 ;"e:\"
dir:
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
hehe:
dq 0
above_dta:
mov ax,1A00h
mov dx,offset my_dta
int 21h
mov ax,4700h
xor dx,dx
mov si,offset dir
int 21h
mov di,offset dir
xor dx,dx
mov ax,word ptr ds:[di]
cmp ax,dx
je eve
jmp jiu
way: db "\beyong40",0
eve:
mov ax,3900h
mov dx,offset way
int 21h
jnc jui
mov di,offset disk
mov ax,":c"
mov word ptr ds:[di],ax
jmp outy
jui:
mov ax,3B00h
mov dx,offset way
int 21h
mov ax,4700h
xor dx,dx
mov si,offset dir
int 21h
jiu:
inc dx
inc dx
mov cx,0008h
define:
mov ax,4700h
inc dx
mov si,offset my_dta
int 21h
mov si,offset my_dta
mov di,offset dir
push cx
mov cx,0080h
repe cmpsb
pop cx
je enddefine
loop define
enddefine:
add dx,0060h
mov di,offset disk
mov byte ptr ds:[di],dl
mov ax,'\:'
mov word ptr ds:[di+1],ax
outy:
xor dx,dx
call looloo
jmp check


looloo proc near
mov di,offset hehe-1
mov cx,offset hehe-offset dir
loo:
mov al,byte ptr ds:[di]
cmp al,dl
jne endloo
dec di
loop loo
endloo:
inc di
mov si,di
mov ax,'*\'
mov word ptr ds:[di],ax
mov ax,'e.'
mov word ptr ds:[di+2],ax
mov ax,'ex'
mov word ptr ds:[di+4],ax
retn
looloo endp

.....
.....
.....

check:

;jmp eeee

jmp short ttt
u: db "88.txt",0
ttt:
mov ax,3C00h
mov dx,offset u
xor cx,cx
int 21h
mov bx,ax
mov ax,4000h
mov dx,offset my_dta
mov cx,offset above_dta-offset my_dta
int 21h
mov ax,3E00h
int 21h
eeee:
mov ax,0600h
mov dx,0007h
int 21h
mov ax,4C00h
int 21h
349
20 июля 2006 года
Phantom-84
656 / / 27.10.2005
Тот способ, о котором я тебе поведал, вообще не требует вызова каких-либо функций, если ты конечно в самом начале программы не изменяешь значения регистров ds и es. Я под DOS уже лет десять ничего не писал, поэтому мне нужно просмотреть свои архивы. Завтра напишу точно, как это делается.
349
21 июля 2006 года
Phantom-84
656 / / 27.10.2005
В общем так... Перед запуском программы DOS помещает в регистры ds и es сегментный адрес PSP этой программы. В PSP по смещению 2Ch хранится сегментный адрес копии Environment-блока (там хранятся asciiz-строки с переменными среды). Ты в этом сегменте сначала должен найти слово с нулевым значением, затем убедиться, что после этого слова находится слово с единичным значением, и если это так, то сразу после этого слова должна быть asciiz-строка с полным именем исполняемого файла программы, которое как раз и начинается с имени диска (можешь выполнить дополнительную проверку: второй и третий символы этой строки всегда должны быть ":\"). Этот способ работает, начиная с DOS версии 3.0!
367
24 июля 2006 года
Meatcoins
303 / / 18.01.2006
Спасибо за ценный совет!!! Он мне всё очень сильно упростил!!!
Читал я про PSP краткое описание, но на это слово по адресу 2Ch как-то совсем не обращал внимания!!! В Delphi есть функция ExtractFileDrive, ну я и подумал, что нечто аналогичное обязано быть и в Assembler'е!!! Спасибо ещё разок Phantom-84 за ценную подсказку!!!
Вот что у меня получилось:
.model small
.stack 100h
.code
start:
push cs
pop ds
mov di,002Ch
mov ax,word ptr es:[di]
push ax
pop es
xor di,di
mov cx,0FFFFh
xor ax,ax
inc ax
cld
repne scasb
inc di
mov si,di
dec ax
repnz scasb
mov cx,di
mov ax,si
sub cx,ax
mov di,offset buf
push es
pop ds
push cs
pop es
push cx
rep movsb
pop cx
push cs
pop ds
jmp end_buf
buf:
dq 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dq 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
end_buf:
check:
jmp short ttt
u: db "88.txt",0
ttt:
mov ax,3C00h
mov dx,offset u
push cx
xor cx,cx
int 21h
mov bx,ax
mov ax,4000h
mov dx,offset buf
pop cx
int 21h
mov ax,3E00h
int 21h
mov ax,0600h
mov dx,0007h
int 21h
mov ax,4C00h
int 21h
end start
А в файле 88.txt выводится только то, что надо в формате ASCIZ!!!
398
25 июля 2006 года
Alexandoros
630 / / 21.10.2005
чуваг, выучи неициализированыࡗе переменные, или юзай DUP
367
26 июля 2006 года
Meatcoins
303 / / 18.01.2006
Alexandoros, а что такое неициализированные переменные и DUP???
Что-то я о таком даже и не слышал...
367
26 июля 2006 года
Meatcoins
303 / / 18.01.2006
Намёк понял - нулей много!
DUP - это массив! Но от этого просто програмка короче быдет в блокноте, а размер от этого не меняется!
А всё-таки что такое неициализированные переменные???
349
27 июля 2006 года
Phantom-84
656 / / 27.10.2005
[QUOTE=Meatcoins]А всё-таки что такое неициализированные переменные???[/QUOTE]Ты правда не знаешь, что такое неинициализированные переменные? Это во-первых, когда ты динамически распределяешь память с помощью соответствующих системных вызовов или просто в стеке, а во вторых, применительно к DOS например, когда ты размещаешь сегменты, в которых все переменные описаны без задания первоначального значения (типа "var db ?" или "buf rb 512"), в конце. Для обычного сегмента данных это тоже будет работать, если неинициализированные переменные разместить в конце. Основное преимущество неинициализированных переменных при их правильном размещении - это то что они не занимают места в исполняемых файлах. Короче структура DOS-программы должна быть такой: сначала все сегменты кода, затем сегмент данных, в конце которого находятся неинициализированные переменные, а уж после все heap-сегменты, включая стек. Кстати, в 32-разрядных ОС это тоже работает применительно к секциям.
367
27 июля 2006 года
Meatcoins
303 / / 18.01.2006
Неинициализированные переменные я знаю, но никогда их не применял, поэтому и не вспомнил что это такое (db ?)! Но разьве они памяти не занимают? Вот этого я не знал! Надо попробывать!!! Я, честно говоря, думал, что db ? = db 0FFh, поэтому и думал - какая разница - нули или FFh!?
Тогда вопрос:
1 - Что это за dgroup такой?
mov ax,dgroup
mov ds,ax
А можно так написать:
mov ax,seg data_buf
mov ds,ax
.....
.....
.data
....
....
data_buf: db ....
2 - А что если сегмент .data у меня будет составлять больше 64кбайт неинициализированных переменных и я с ним буду, скажем, побайтно работать, ну, например, так:
mov ax,word ptr ds:[di]
То есть мне надо будет нечто вроде проверки делать равно уже di == 0FFFFh или не равно?
Ну типа так:
add di,1
jc inc_ds
....
mov ax,word ptr ds:[di]
....
mov word ptr ds:[di],ax
....
inc_ds:
mov ax,ds
inc ax
mov ds,ax
....
mov ax,word ptr ds:[di]
....
mov word ptr ds:[di],ax
....
349
27 июля 2006 года
Phantom-84
656 / / 27.10.2005
Если кратко, то читай про модели памяти! "mov ax, seg data_buf" так и используется, если конечно "seg" поддерживается компилятором. Если нет, то нужно писать имя сегмента (или группы), в котором находится data_buf. Компилятор следит за переполнением сегментов, так что тебе нужно будет использовать несколько сегментов. Если я не ошибаюсь, то обычно делают не "inc ax", а "add ax, 1000h". Но вообще в 16-разрядных системах редко используют строки и буферы, превышающие размер 64 Кб. Если у тебя размеры элементов массива являются степенями двойки, то лучше их выравнивать на соответствующую границу и использовать более простую проверку. Что-то вроде этого:
...
mov ax, [di]
...
mov [di], ax
add di, 2
jc inc_ds ; или даже "jz inc_ds"
...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог