Page 1 of 1
SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Sat Oct 29, 2016 1:04 am
by 0CodErr
Returned value:
* eax = -1 - error (access to PCI is disabled or parameters
are not supported); otherwise
* al/ax/eax (depending on requested size) contains the data;
the other part of register eax is destroyed
А что, если
data = -1? Это ведь будет не отличить от
error.
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Mon Oct 31, 2016 10:45 am
by art_zh
0CodErr
FFFFFFFF - это дефолтное состояние по стандарту PCI.
Так что если ты прочитал -1 из стандартного регистра, то он либо неинициализирован, либо обращение было направлено к пустому слоту.
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Mon Oct 31, 2016 10:54 am
by 0CodErr
art_zh, спасибо, теперь понятно, почему так.
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Mon Oct 31, 2016 10:47 pm
by 0CodErr
Я делаю обёртки для своей KolibriOS библиотеки.
Всё правильно, надеюсь?
Spoiler:
Code: Select all
(* -------------------------------------------------------- *)
{62.0} Function GetPCIVersion: Dword; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 0
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.1} Function GetLastPCIBus: Dword; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 1
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.2} Function GetPCIAddressingMode: Dword; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 2
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.3} {UNDEFINED}
(* -------------------------------------------------------- *)
{62.4} Function ReadPCIByte(Bus, Device, Func, Reg: Byte): Byte; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 4
mov bh, Bus
mov cl, Reg
mov ch, Device
shl ch, 3
or ch, Func
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.5} Function ReadPCIWord(Bus, Device, Func, Reg: Byte): Word; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 5
mov bh, Bus
mov cl, Reg
mov ch, Device
shl ch, 3
or ch, Func
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.6} Function ReadPCIDword(Bus, Device, Func, Reg: Byte): Dword; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 6
mov bh, Bus
mov cl, Reg
mov ch, Device
shl ch, 3
or ch, Func
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.7} {UNDEFINED}
(* -------------------------------------------------------- *)
{62.8} Function WritePCIByte(Bus, Device, Func, Reg: Byte; Data: Byte): Dword; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 8
mov bh, Bus
mov cl, Reg
mov ch, Device
shl ch, 3
or ch, Func
mov dl, Data
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.9} Function WritePCIWord(Bus, Device, Func, Reg: Byte; Data: Word): Dword; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 9
mov bh, Bus
mov cl, Reg
mov ch, Device
shl ch, 3
or ch, Func
mov dx, Data
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
{62.10} Function WritePCIDword(Bus, Device, Func, Reg: Byte; Data: Dword): Dword; StdCall;
Asm
push ebx
mov eax, 62
mov bl, 10
mov bh, Bus
mov cl, Reg
mov ch, Device
shl ch, 3
or ch, Func
mov edx, Data
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Mon Oct 31, 2016 11:03 pm
by Siemargl
Если паскаль сохраняет используемые регистры, то почти все ОК.
x86 calling convention - AX, CX, DX внутри функций свободно применимы, остальные надо сохранять.
Только не используй Byte в параметрах - только 32-битные параметры.
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Mon Oct 31, 2016 11:31 pm
by 0CodErr
Только не используй Byte в параметрах - только 32-битные параметры.
Siemargl, я по возможности придерживаюсь этого. Но иногда из-за этого пришлось бы делать дополнительные преобразования. С другой стороны, сам вызов
int 64 гораздо медленнее.
Если паскаль сохраняет используемые регистры, то почти все ОК.
x86 calling convention - AX, CX, DX внутри функций свободно применимы, остальные надо сохранять.
Ну я согласно документации делаю:
Register saving conventions
Procedures and functions must preserve the EBX, ESI, EDI, and EBP registers, but can modify the EAX, EDX, and ECX registers. When implementing a constructor or destructor in assembler, be sure to preserve the DL register. Procedures and functions are invoked with the assumption that the CPU's direction flag is cleared (corresponding to a CLD instruction) and must return with the direction flag cleared.
Или вот пример
Spoiler:
Code: Select all
{20.2} Function OutputMidi(Data: Byte): Integer; StdCall;
Asm
push ebx
mov eax, 20
mov ebx, 2
mov cl, Data
int 64
pop ebx
End;
Если было бы не Byte, а Dword, то программист мог бы по ошибке передать значение, выходящее за пределы диапазона Byte, а компилятор промолчал бы. Я считаю, что здесь использование Byte вполне оправдано.
Точно так же ReadPCIByte возвращает байт, что логично, потому что именно байт читали.
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Tue Nov 01, 2016 12:08 am
by Siemargl
0CodErr wrote:Если было бы не Byte, а Dword, то программист мог бы по ошибке передать значение, выходящее за пределы диапазона Byte, а компилятор промолчал бы. Я считаю, что здесь использование Byte вполне оправдано.
Точно так же ReadPCIByte возвращает байт, что логично, потому что именно байт читали.
Проверь, что именно компилятор засовывает в стек. Нужно 32-битное значение (даже если данные там в младшем байте). Иначе будет невозможно нормально вызывать твои функции.
Ну и к интероперабельности - строки только asciiz, структуры (record) с явным выравниванием (или без), выделенная память передаваемая - только через сисфункции.
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Thu Nov 03, 2016 4:54 pm
by 0CodErr
Siemargl, у меня из 260-ти функций только в 50-ти используется Byte, а в остальных Dword\Pointer.
Я проверил, что делает компилятор, перед вызовом функции он делает примерно так
Code: Select all
00000022: 8A 04 24 mov al,byte ptr [esp]
00000025: 50 push eax
То есть, на стеке всё равно будет Dword.
Ну и к интероперабельности - строки только asciiz, структуры (record) с явным выравниванием (или без), выделенная память передаваемая - только через сисфункции.
Это уже всё согласно документации к системным функциям KolibriOS.
Ну и, естественно, что, поскольку функции StdCall, то и использоваться могут не только из Delphi\FreePascal, но и из любого другого, поддерживающего такое соглашение вызова(а его все поддерживают, насколько знаю).
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Thu Nov 03, 2016 8:47 pm
by Siemargl
0CodErr wrote:Siemargl, у меня из 260-ти функций только в 50-ти используется Byte, а в остальных Dword\Pointer.
Я проверил, что делает компилятор, перед вызовом функции он делает примерно так
Code: Select all
00000022: 8A 04 24 mov al,byte ptr [esp]
00000025: 50 push eax
То есть, на стеке всё равно будет Dword.
Хорошо, но желательно чтобы он делал
movzx al,byte ptr [esp]
А то в старших байтах будет мусор
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Thu Nov 03, 2016 9:03 pm
by 0CodErr
Siemargl wrote:Хорошо, но желательно чтобы он делал
movzx al,byte ptr [esp]
Не-не, тут ты не прав, нет такой команды просто.
Если ты имел в виду
movzx eax, то я думаю, что компилятор наверняка следит за использованием регистров.
А то в старших байтах будет мусор
Ну и что с того?
Например, вызываем
Code: Select all
Var MyByte: Byte;
MyByte := ReadPCIByte(Bus, Device, Func, Reg);
А сама функция
ReadPCIByte, как видно в посте выше, не использует никаких старших байтов. А если бы использовала, то следовало объявить параметры не
Byte, а
Dword, например. Ну и тогда, соответственно, компилятор клал бы на стек значение
eax целиком. Проще говоря, компилятор ведёт себя вполне логичным образом.
Более того, под номер функции устройства отводится всего 3 бита.
Так что, можно даже не байт использовать, а определить
далее, меняем тип параметра в функции
ReadPCIByte
И теперь, если передать, например, значение
Func, равное
10, то получим
Constant expression violates subrange bounds
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Fri Nov 04, 2016 1:05 am
by Siemargl
прости, проблемы паскаля меня мало волнуют - ты приводишь примеры, которые разбирает компилятор
а я про более низкоуровневый код
вот тебе несуществующая инструкция
http://x86.renejeschke.de/html/file_mod ... d_209.html
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Fri Nov 04, 2016 1:39 am
by 0CodErr
Не знаю уж, что я там должен был найти, может и плохо искал, конечно. Но вот тебе из мануала
Spoiler:
-
1.PNG (64.87 KiB)
Viewed 8773 times
И никаких
MOVZX reg8, reg/mem8 там и близко нет.
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Sun Nov 06, 2016 2:02 am
by brunnel
0CodErr
Code: Select all
movzx eax, byte ptr [esp]
push eax
Re: SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
Posted: Mon Nov 07, 2016 5:08 pm
by 0CodErr
brunnel, yes, i noticed
Siemargl about it in the post above.
Если ты имел в виду movzx eax, то я думаю, что компилятор наверняка следит за использованием регистров.
But it seems that
Siemargl think that the compiler was made by stupid people who can not in the basic things.
Also,
movzx eax, byte ptr [esp] - It is not necessary. Because ReadPCIByte function does not use the high bytes of eax. So the compiler is right.