|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Апр 16, 2004 17:22:35 · Поправил: Безпощадный даос Ув. коллеги! Я написал прогу-гибрид из Си и Асма для получения физических параметров харда (головки, сектора, дорожки) при помощи Int13(48h) и вот в чём дело... Мой код: 1 #include <iostream.h> 2 void main() 3 { 4 unsigned long int sec; 5 unsigned long int head; 6 unsigned long int cyl; 7 unsigned long int sec1; 8 unsigned long int head1; 9 unsigned long int cyl1; 10 unsigned long int buf; 11 unsigned long int tot; 12 asm { 13 mov ah, 0x48; 14 mov dl, 0x80; 15 lea si, buf; 16 int 0x13; 17 18 mov ax, ds:[si+4]; 19 mov word ptr cyl[0], ax; 20 mov ax, ds:[si+8]; 21 mov word ptr head[0], ax; 22 mov ax, ds:[si+16]; 23 mov word ptr sec[0], ax; 24 } 25 26 tot=cyl1*head1*sec1/2048; 27 cout << "Cylinders= " << cyl1; 28 cout << " Heads= " << head1; 29 cout << " Sectors= " << sec1; 30 cout << " Total= " << tot << " Mb"; 31 } сразу хочу сказать, что прога работает! Проблемы вот в чём: Int 13h требует зарезервировать место в памяти (74 байта, по идее), но при попытке написать что-то вроде buf dw 74 dup ? и любые вариации на эту тему внутри асм"овского кода, компилятор ругается... зато его устраивает, когда я силами Си определяю buf как unsigned long int (это в 16 раз меньше того, что необходимо!!!) Дальше - хуже... Когда я запускаю прогу в пошаговом режиме, то после выполнения 16-й строки я вижу, что в переменных cyl, sec, head уже есть необходимые мне значения, хотя я собирался заносить их туда в строках с 18 по 23! Каким образом он заносит туда инфу автоматически?! я вупор не понимаю! Эти строки можно убрать, но при попытке вывести на экран значения функцыей cout, прога виснет... Ещё одна любопытная вещь - в зависимости от того, в какой очерёдности я определяю переменные (в частности buf), значения заносятся либо в sec, head, cyl, если 10-ю строку записать после 6-й, либо они заносятся в переменные cyl1, sec1, head1, если её оставить нa месте... Вам я представил конечный вариан проги... Бред заключается в том, что: она работает!, не зависает!, всё нормально выводит на экран!, но НИКАКОЙ логической связи между переменным я не вижу! Компилировал в Билдере 3.1 Может быть кто-то что-то может мне объяснить? Помогите, пожалуйста! |
|
|
Дата: Апр 16, 2004 17:55:05 Прежде всего: этот код компилирован как 16-бит или 32-бит? Теперь о проблеме: переменные у Вас - объявлены в стеке. Некоторые компиляторы выстраивают их в обратном порядке, то есть (в вашем случае) первой в памяти расположена переменная tot, а последней - sec. Прерывание пишет 74 байта по адресу buf, а за buf расположено всё остальное: cyl1,head1,sec1,... Кстати, там не хватит места на 74 байта - так что скорее всего вытирается часть стека ЗА переменными, но поскольку это main() - стек не так важен. Надо просто сделать структуру вместо buf и тогда всё заработает и не надо ничего пересылать после отработавшего прерывания:
typedef struct
{
unsigned long int _1;
unsigned long int _2;
unsigned long int _3;
// more here ...
}
HDD_INFO;
void main ()
{
HDD_INFO buf;
...
}
|
|
|
Дата: Апр 16, 2004 18:54:40 На счёт 16-и или 32-х битовый код... это от чегно зависит? Если от проца - то тогда как 32-х... На счёт остального... Со структурой попробую, но дело не втом, что не работает (оно-то работае)? Вопрос в том - почему? Ведь (при условии, что я не совсем пальцем деланный) по логике я должен получать всё, что угодно, но никак уж не результат (правильный!)... Вот меня и интересует: как исходя из того, что написано в коде, оно может работать? |
|
|
Дата: Апр 17, 2004 07:39:32 Nos Компилировал в Билдере 3.1 Может быть в BC++v3.1? Ты уверен, что int13h отработала успешно? Ты вообще читал описание Int 13h Fn=48h? До вызова этой функции необходимо в первое слово по адресу ds:si занести размер передаваемого буфера, который определяет версию затребованной информации. AsmGuru62 поскольку это main() - стек не так важен По-твоему затереть адрес возврата из main нельзя? |
|
|
Дата: Апр 19, 2004 15:14:24 Описание читал! И прога работает! В этом-то всё и дело, что по идее работать либо не должно, либо очень криво, но тем не менее - работает... компилировал в ВС++v3.1 |
|
|
Дата: Апр 20, 2004 05:09:46 · Поправил: q_q Nos Описание читал Внимательно? Откуда информация про 74 байта? Я вижу максимум 66. Где проверка поддержки IBM/ms Int13h Extensions? Где инициализация первого слова? Где проверка успешного выполнения Int13h? тем не менее - работает AsmGuru62 заметил совершенно справедливо компиляторы выстраивают их в обратном порядке. Посмотри листинг ...
_main proc near
push bp
mov bp,sp
sub sp,20h
push si
;
; {
; unsigned long int sec;
; unsigned long int head;
; unsigned long int cyl;
; unsigned long int sec1;
; unsigned long int head1;
; unsigned long int cyl1;
; unsigned long int buf;
; unsigned long int tot;
; asm {
; mov ah, 0x48;
;
mov ah, 048h
;
; mov dl, 0x80;
;
mov dl, 080h
;
; lea si, buf;
;
; !!! адрес переменной buf
lea si, [bp-1Ch]
;
; int 0x13;
;
int 013h
; манипуляции с cyl, head и sec пропущу
...
;
; tot=cyl1*head1*sec1/2048;
;
; !!! адрес переменной cyl1
mov cx,word ptr [bp-16h]
mov bx,word ptr [bp-18h]
; !!! адрес переменной head1
mov dx,word ptr [bp-12h]
mov ax,word ptr [bp-14h]
call near ptr N_LXMUL@
push ax
push dx
; !!! адрес переменной sec1
mov dx,word ptr [bp-0Eh]
mov ax,word ptr [bp-10h]
pop cx
pop bx
call near ptr N_LXMUL@
; !!! сдвиг на 11 эквивалентен делению на 2048
mov cl,11
call near ptr N_LXURSH@
; !!! запись tot
mov word ptr [bp-1Eh],dx
mov word ptr [bp-20h],ax
...получается что в памяти переменные cyl1, head1 и sec1 расположены как соответствующие элементы структуры ожидаемой на выходе из Int13h.
По поводу возможного затирания адреса возврата из main. В случае когда запрошена информация для IBM/ms Int13h Extensions версии 1.x или 2.x Int13h заполняет 1Ah или 1E байт соответственно, твоя программа имеет в запасе 1Ch плюс два байта на сохранение регистра bp итого 1Eh. |
|
|
Дата: Апр 21, 2004 18:24:44 · Поправил: Nos Откуда информация про 74 байта? Я вижу максимум 66. Это я прикинул из документации: "offset 73, type - byte"... получается что в памяти переменные cyl1, head1 и sec1 расположены как соответствующие элементы структуры ожидаемой на выходе из Int13h. Это я уже понял - поменял их местами и посмотрел, чё он там пишет... Продолжаем разговор...8-) Как-то вычитал, что: "Трёхмерные параматры могут быть недействительны, если число секторов более 15482880..." и вот моя прога работает, так сказать, местами... Я имею 40-а гиговый Samsung. На моём компе прога выдаёт 19177 дорожек, 16 головок, 255 секторов на дорожку... (в БИОСе тоже самое в режиме normal) На другом компе с таким же винтом выдаёт соответственно 4870/255/63 - это, по-моему, логические параметры. Ставлю этот чужой винт на свой комп, имею: 19177/16/255. На третем компе выдаёт нормальные параметры (соответсвуют параметрам БИОСа в режиме normal, и винт там другой) Остальные эксперементы опысивать не буду, но смысл в том, что однозначно правильно я считываю только общее кол-во секторов, а остальное - как повезёт... Методы борьбы с этим есть? Может с АТА-коммандами кто-то знаком? |
|
|
Дата: Апр 22, 2004 04:39:26 Может это поможет? |
|
|
Дата: Апр 22, 2004 08:22:12 Зайди на t13.org там куча документации по работе с ата коммандами, и кстати работать с ними оказалось проще чем через гребаный биос (понимаю создателей линукса),могу даже исходничков подкинуть(только как дома буду) по чтению записи + установка пароля на винт :) после чего винт можно выкидывать + еще любую ата команду можно поставить ... ПС документы там на англицком |
|
|
Дата: Апр 22, 2004 16:20:49 · Поправил: Nos За просмотр содержимого на t13.org я уже взялся... интересно, какой-нить добрый человек перевёл это для простых смертных на русский язык? А исходники будут очень кстати - может пойму как с этими коммандами работать... |
|
|
Дата: Апр 24, 2004 16:49:38 только осторожнее , эта штука реально убивает хард навсегда ..... и еще ктото в моду взял мои проги к своим вирям цеплять , эту то хоть ненадо 1575515596__old.bat |
|
|
Дата: Апр 26, 2004 15:52:05 · Поправил: Nos Не прицеплю - меня реально интересует просто технология работы с ата... А вас не затруднит прокоментировать каждую (по возможности) строку своей проги? |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.061 |