Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Адресация внутри регистров 
:(
    Опции темы
Nos
  Дата 9.4.2004, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 29.3.2004

Репутация: нет
Всего: нет



Ув. коллеги! Ситуация такова: я получаю адрес начала таблици в регистрах es:bx, мне необходимо считать из неё пару ячеек со смещениями 0, 2, 14 байт... как это сделать правильно? Я пробовал mov ax, es:[bx+ (кол-во байт)], но судя по тому, какую х... я от туда считываю, что-то делаю не так... помогите, плиз!
PM MAIL   Вверх
DenDen
Дата 9.4.2004, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 25.3.2004

Репутация: нет
Всего: нет



push ds
push es
pop ds
add bx,2;
mov ax,[bx]
//////
pop ds
Если проблема только в замене сегмента и сегмент ты можешь заменять(Linux обычно дает по шапке).Скорее всего проблема в самой таблице.

PM MAIL   Вверх
Nos
Дата 9.4.2004, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 29.3.2004

Репутация: нет
Всего: нет



Проблема с таблицей, говоришь... может быть. Дело в том, что в эти регистры указывают мне адрес таблицы параметров харда (HDTP), первые 2 байта показывают кол-во дорожек (здесь претензий нет - всё нормально), 3-й байт должен рассказать сколько головок, а 15-й кол-во секторов на дорожку (по идее)... и вот в этих полях у меня и начинается полный бред...
А почему нельзя es:[bx+2]?
PM MAIL   Вверх
Akina
Дата 9.4.2004, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: нет
Всего: 454



Цитата
А почему нельзя es:[bx+2]?

можно, можно... а вот почему ты получаешь шелуху - это вопрос... потрасси и глянь куда тебя уносит...

Попробуй, кстати, декомпильнуть собранный код - есть ли override сегмента? а то попробуй не
Код
mov ax,es:[bx+2]

а
Код
db 26h
mov ax, word ptr [bx+2]

PM MAIL WWW ICQ Jabber   Вверх
DenDen
Дата 9.4.2004, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 25.3.2004

Репутация: нет
Всего: нет



Зависит от асма.
На турбо-асме он выкидывает ворнинг, что игнорирует ":", посему приходится менять сегмент вручную.(по умолчанию ds)
На флате вроде работает ничего.
Попробуй сделать как написано, если не получиться(и ни 1 большой человек не выскажет свое фи по поводу вышенаписанного), то скорее всего дело в таблице.Если получиться, то получиться.
PM MAIL   Вверх
Nos
Дата 9.4.2004, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 29.3.2004

Репутация: нет
Всего: нет



Забыл сказать... я делаю гибрид из Си и Асма (работаю в Билдере 3.1) Си использую для вывода на экран, а в Асме работаю с регистрами...
Попробую... надо позарез!
Может исходники глянете?
PM MAIL   Вверх
Chingachguk
Дата 9.4.2004, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: нет
Всего: 18



Код дай...


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Nos
Дата 9.4.2004, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 29.3.2004

Репутация: нет
Всего: нет



1 #include <iostream.h>
2 void main()
3 {
4 unsigned int cyl;
5 unsigned int heads;
6 unsigned char head;
7 unsigned int sec;
8 unsigned long int a;
9 unsigned long int b;
10 unsigned long int tot;
11 asm mov ax, 0x3541;
12 asm int 0x21;
13 asm mov ax, es:[bx+0];
14 asm mov cyl, ax;
15 asm mov ax, es:[bx+0x2];
16 asm mov head, al; //считывать нужно первые 8 бит вроде бы
17 asm mov ax, es:[bx+0xE];
18 asm mov sec, ax;
19 a = cyl; //
20 b = a * sec; // в одной строке перемножается почему-то неправильно
21 tot = b * head;//
22 heads = tot/b;//head объявлена как char и вместо числа выдаёт символ, пришлось хитрить...
23 cout << "Cylinders = "<< cyl;
24 cout << " Heads = " << heads;
25 cout << " Sectors = " << sec;
26 cout << " Total = " << tot;
27 }
PM MAIL   Вверх
Nos
Дата 9.4.2004, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 29.3.2004

Репутация: нет
Всего: нет



Цитата
то скорее всего дело в таблице

...ещё по-поводу таблицы: то что первые три байта содержат кол-во дорожек и головок я уверен на 100% - в нескольких источниках смотрел, а вот по поводу того, что в 15-м кол-во секторов на дорожку - в документации ничего об этом не сказано, я это вычислил из кода проги на асме, которую мне на форуме каком-то дали (не помню, к сожалению на каком)... может быть вы знаете, содержит ли вообще эта таблица (HDTP) информацию о секторах?
PM MAIL   Вверх
Akina
Дата 9.4.2004, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: нет
Всего: 454



Цитата
INT 41 - FIXED DISK PARAMETERS (XT,AT,XT2,XT286,PS except ESDI disks)

00 ORD    cylinders
02 BYTE    heads
03 WORD    starting reduced write current cylinder (XT only, 0 for others)
05 WORD    starting write pre-comp cylinder
07 BYTE    maximum ECC burst length
08 BYTE    control byte
                  bits 0-2: drive option (XT only, 0 for others)
                  bit 3:    set if more than 8 heads
                  bit 4:    always 0
                  bit 5:    set if manufacturer's defect map on max cylinder+1
                  bit 6:    disable ECC retries
                  bit 7:    disable access retries
09 BYTE    standard timeout value (XT only, 0 for others)
0A BYTE    formatting timeout value (XT only, 0 for others)
0B BYTE    timeout value for checking drive (XT only, 0 for others)
0C WORD    landing zone (AT/PS2)
0E BYTE    sectors/track (AT/PS2)
0F BYTE    0

Подробности - в Ralf Brown Interrupt List.
PM MAIL WWW ICQ Jabber   Вверх
Chingachguk
Дата 10.4.2004, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: нет
Всего: 18



По поводу получения параметров диска была тема:

http://forum.vingrad.ru/index.php?showtopic=20370

(ты же спрашивал - ?)

Насчет того, что у тебя "полный бред" в количестве головок и тд так это очень может быть и не бред, а связано с тем, что давно-давно, когда винты были по 40 мегабайт, количество секторов и тп вполне вмещалось в отведенные ячейки памяти. Сейчас же все стало иначе, поэтому стали делать "нереальное" число головок и тп. Посмотри мой исходник - он же на эту тему: я как раз читал сектора, опираясь на инфу из int 41h:

Цитата

  push offset MyHardDiskParams
  call GetHard80h_Info_by_INT41      ; Получить инфу по int 41h
  push offset MyLogDiskStruc
  call GetHard80h_Info_by_MBR          ; Прочтя MBR

; Вычислить номер головки

  mov  ax,MyLogDiskStruc.LastCylSec
  push ax
  and  al,00111111b
  mov  byte ptr CurrSect,al
  pop  ax
  and  al,11000000b
  xchg al,ah
  shr  ah,6
  mov  dh,MyLogDiskStruc.LastHead  ;
  push dx
  and  dh,11000000b
  or  ah,dh
  mov  word ptr CurrCyl,ax
  pop  dx
  and  dh,00111111b
  mov  byte ptr CurrHead,dh

...

; Сравнить с тем, что дал нам int 41h

  mov  al,byte ptr CurrHead
  cmp  al,byte ptr MyHardDiskParams.Heads
  jb  @@UseTheseCylHead
 


В си можно все делать неплохо, опираясь на стандартные средства (вроде):

Цитата


struct
{
  unsigned int    number_of_cylinders;
  unsigned char number_of_heads;
  unsigned int    starting_reduced_write_current_cylinder;
  unsigned int    starting_write_precompensation_cylinder_number;
  unsigned char maximum_ECC_burst_length;
  unsigned char control_byte;
  unsigned char standard_timeout;
  unsigned char formatting_timeout;
  unsigned char timeout_for_checking_drive;
  unsigned int  cylinder_number_of_landing_zone;
  unsigned char number_of_sectors_per_track;
  unsigned char reserved;
} tHDTP;

asm {
mov ax, 0x3541
int 0x21
mov ax, es:[bx].number_of_cylinders
mov cyl,ax
mov al, es:[bx].number_of_heads
}

// Или так - я си не знаю:

#define tPtrtHDTP= *tHDTP // Типа того
tPtrtHDTP PtrtHDTP;
tHDTP HDTP;

asm {
mov ax, 0x3541
int 0x21
mov  word ptr ds:PtrtHDTP,bx
mov  word ptr ds:PtrtHDTP+2,es
}

memcpy(&HDTP,(char *)PtrtHDTP,sizeof(tHDTP));

printf("number_of_heads:%02x",HDTP.number_of_heads);



А делал я это вот зачем (моя неопубликованная "статья"):

Цитата

Данный док о том, как не надо читать сектора.

Итак, как гласит документация(Ральф Браун), при чтении сектора(ов) мы должны задать
BIOS следующие параметры:

Цитата

INT 13 - DISK - READ SECTOR(S) INTO MEMORY
AH = 02h
AL = number of sectors to read (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5)
      high two bits of cylinder (bits 6-7, hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
Return: CF set on error
    if AH = 11h (corrected ECC error), AL = burst length
CF clear if successful
AH = status (see #0144)
AL = number of sectors transferred (only valid if CF set for some
      BIOSes)
Notes: errors on a floppy may be due to the motor failing to spin up quickly
  enough; the read should be retried at least three times, resetting
  the disk with AH=00h between attempts
most BIOSes support "multitrack" reads, where the value in AL
  exceeds the number of sectors remaining on the track, in which
  case any additional sectors are read beginning at sector 1 on
  the following head in the same cylinder; the CONFIG.SYS command
  MULTITRACK can be used to force DOS to split disk accesses which
  would wrap across a track boundary into two separate calls
the IBM AT BIOS and many other BIOSes use only the low four bits of
  DH (head number) since the WD-1003 controller which is the standard
  AT controller (and the controller that IDE emulates) only supports
  16 heads
AWARD AT BIOS and AMI 386sx BIOS have been extended to handle more
  than 1024 cylinders by placing bits 10 and 11 of the cylinder number
  into bits 6 and 7 of DH
under Windows95, a volume must be locked (see INT 21/AX=440Dh/CX=084Bh)
  in order to perform direct accesses such as INT 13h reads and writes
SeeAlso: AH=03h,AH=0Ah,AH=06h"V10DISK.SYS",AH=21h"PS/1",AH=42h"IBM"
SeeAlso: INT 21/AX=440Dh/CX=084Bh,INT 4D/AH=02h


Откуда видно, что для задания начального сектора для чтения необходимы три параметра:

- Головка(Head);
- Дорожка или Цилиндр (Cylinder);
- Номер сектора на дорожке(цилиндре ?) - Sector.

Из описания ф-ции 2 прерывания int 13h видно, что делатется это следующим образом:

Регистр CX Биты/Назначение
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
C C C C C C C C C C S S S S S S

Регистр DH Биты/Назначение
7 6 5 4 3 2 1 0
C C H H H H H H

C - сокращение от Cylinder, S - сокращение от Sector, H - сокращение от Head.

Мой диск (параметры взяты из Setup BIOS и они идентичны содержимому таблицы, адрес
которой хранит вектор int 41h) содержит следующие параметры:

BIOS AWARD ROM PCI/ISA
Primary Master
TYPE SIZE CYLS HEAD PRECOMP LANDZ SECTOR MOD
User 1207 585 64 0 2339 63 LBA

Итак, у меня диск объемом ~1207 МБайт. Как же соотносится эта величина с количеством
секторов, цилиндров и головок ? Раз тут подразумевается, что указываются МАКСИМАЛЬНЫЕ
значения (а что еще ?), то несложное перемножение должно нам дать показанный объем:

HEAD * CYLS * SECTOR * (512байт в МБайтах) ~= 1207МБайт ?

512 байт - размер в байтах одного сектора. В мегабайтах это будет:
Размер сектора в МБайтах = 512/1МБайт = 200h/100000h = 1/2048 МБайт.

HEAD * CYLS * SECTOR * (512байт в МБайтах) ~= 64 * 585 * 63 * 1/2048 ~=
~= 1152 МБайт < 1207 МБайт ?

Итак, декларированное BIOS и поддерживаемое программным интерфейсом (содержимое
вектора int 41h) число CYLS, HEAD и SECTOR не дает нам полного объема диска ?
Куда же девались эти 1207- 1152 = 55 МБайт ?!
...
Выполним последовательное чтение сектора номер 1 с цилиндра 584(максимальный номер)
на разных Head:

Cylinder = 584
Head (биты 0-5 в регистре DH)
0 Сектор прочитан
30 Сектор прочитан
63 Сектор прочитан

Пока все нормально, в пределах декларированных BIOS параметров.
Предположим, что реальное число цилиндров больше декларированного.
Тогда чтение с цилиндров 585.. может дать нам дополнительные(недостающие) сектора:

Cylinder = 585
Head (биты 0-6 в регистре DH)
0 Сектор не прочитан
30 Сектор не прочитан
63 Сектор не прочитан

Номер ошибки - 0Ah:

Цитата

Ральф Браун:
0Ah bad sector detected (hard disk)


Итак, номер цилиндра не может превышать установленного в BIOS. Однако обратим внимание
вот на этот комментарий к ф-ции чтения сектора:

Цитата

AWARD AT BIOS and AMI 386sx BIOS have been extended to handle more
than 1024 cylinders by placing bits 10 and 11 of the cylinder number
  into bits 6 and 7 of DH


Ага, тут говриться, что номер цилиндра, если цилиндров > 1024 (номер не может быть
размещен в битах 8-15 и 6-7 регистра CX), помещается также в биты 6-7 регистра DH.

Или вот еще цитата(http://www.citforum.ru/pp/pc03_09.shtml):

Цитата

...Также, в силу исторических причин, многие операционные системы,
работающие с накопителями на ЖМД через BIOS, разработаны таким образом,
что не могут оперировать числом цилиндров более 1024. Поскольку в настоящее
время, накопители больших объемов (более 1Мб) имеют более 1024 физических
цилиндра, то применяется программный пересчет, при котором, накопитель
определяется его контроллером и процедурами BIOS как имеющий не более
1024 цилиндра, но имеющий некоторое нереальное число головок, поверхностей
и секторов. Функция же пересчета для отыскания нужного сектора ложится
либо на BIOS ПК, либо на BIOS контроллера, либо на интерфейс.


Выполним последовательное чтение сектора номер 1 с цилиндра 584(максимальный номер)
на разных Head:

Cylinder = 584
Head Low/High (биты 0-5 в регистре DH/биты 6-7 в регистре DH) = содержимое DH
0/1 = 40h Сектор не прочитан
30/1 = 5Eh Сектор не прочитан
63/1 = 7Fh Сектор не прочитан

Ошибка прежняя - 0Ah.

Итак, получается в некотром роде странная сиуация: мы должны "растянуть" число
битов, отводимое под номер цилиндра(по Ральфу Брауну), чтобы правильно описывать
большие диски. Но чтение даже с CYLS+1 цилиндра приводит к ошибке. Т.е. "цилиндров"
у нас по прежнему не более CYLS. Первая попытка увеличить число головок до 65 к успеху
не привела. Может быть, на этих "дополнительных" головках не CYLS цилиндров, а меньше ?!
Проверим это таким чтением:

Cylinder = 1
Head Low/High (биты 0-5 в регистре DH/биты 6-7 в регистре DH) = содержимое DH
0/1 = 40h Сектор прочитан !
Cylinder = 584
Head Low/High (биты 0-5 в регистре DH/биты 6-7 в регистре DH) = содержимое DH
0/1 = 40h Сектор не прочитан !

Очень интересно ! А на сколько меньше ? Попробуем увеличивать номер цилиндра для
этой головки:

Head Low/High: 0/1 = 40h
Cylinder
1 Сектор прочитан
100 Сектор прочитан
200 Сектор прочитан
300 Сектор прочитан
583 Сектор прочитан
584 Сектор не прочитан !
...

Та же самая картина и для Head-Low 30 и 63 - последний доступный цилиндр 583.

А какое максимальное число цилиндров можно задавать для Head-High = 2 и 3 ?
Т.е. если DH=10??????b и DH=11??????b. Повторим предидущий опыт для этих
значений и вот что оказалось:

Для Head-High = 2 - 582 цилиндра, для Head-High = 3 - 581 цилиндр.

Итак, если мы зададим в битах 6 и 7 регистра DH ненулевые значения, то максимально
доступный номер цилиндра станет 584-DH-High вместо 584.

Может быть, задавая в битах 6 и 7 регистра DH дополнительную информацию, мы просто
по-иному задаем какой-либо сектор, доступный обычным способом (без установки этих бит) ?
Это легко проверить. Прочтем какой-нибудь сектор, установив один или оба этих бита в 1, а
потом прочтем все возможные сектора, доступные нам без установки этого бита, при этом
будем сравнивать с ними исходный сектор. Очевидно, нам нужно перебрать все комбинации
значения головок в диапазоне 0..HEAD-1, а цилиндров - 0..CYLS-1, что составляет в случае
моего винта 0..63 для головок и 0..584 для цилиндров. Вот результат этого опыта:

Начальный сектор Совпавший с ним сектор
DH-High/Low Cyl Sect DH Cyl Sect
1/0 0 1 0 1 1
2/0 0 1 0 2 1
3/0 0 1 0 3 1
3/1 0 1 1 3 1
3/63 0 1 63 3 1
1/0 1 1 0 2 1
1/0 2 1 0 3 1
1/0 3 1 0 4 1
2/0 1 1 0 3 1
1/0 255 1 0 256 1
1/3 255 63 3 256 63
2/3 255 63 3 257 63
3/3 255 63 3 258 63

Получается, что в случае Cyl = 0 DH-high как бы просто складывается с номером цилиндра !
И в результате заполнение DH-High - это просто иной способ чтения секторов, доступных
в обычном режиме ? Как же в таком случае все же прочесть недостающие 50 Мегабайт ?!

А оказалось все ГОРАЗДО проще: просто объем диска дается в БАЙТАХ:

585 цилиндров x 64 головки x 63 сектора x 512 байт в секторе = 1 207 664 640 байт ! ;)

Вот и все.






--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
p0s0l
Дата 10.4.2004, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 2
Всего: 112



Nos, может проблема в том, что у тебя es и bx портятся ? Поди Си использует эти регистры для своих нужд, а ты раз и изменил их ? Поэтому у тебя может значения-то нормальные берутся из HDTP, но при засовывании в переменную улетают куда-нить не туда, или cout не то выводит. Короче, лучше запоминай, а потом восстанавливай все реги, на всякий пожарный (pusha/popa)...




--------------------
С уважением, г-н Посол.
PM   Вверх
Nos
Дата 13.4.2004, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 29.3.2004

Репутация: нет
Всего: нет



Спасибо всем за содействие и желание помочь, уже всё работает! Ошибки были элементарнишие - в моём исходнике необходимо переменную sec определить, как unsigned char, и в нескольких местах работать не со всем регистром ах, а только с половиной...
PM MAIL   Вверх
Jin X
Дата 13.4.2004, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 5.3.2004

Репутация: 1
Всего: 1



Кто ж сейчас использует функции ah=0xh/int 13h, пора уже переходить на ah=4xh/int 13h: http://t13.org/docs2004/d1572r1a.pdf
--------------------
Бойся своей мечты, ибо она осуществима!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm: Общие вопросы"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0611 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.