А что, если data = -1? Это ведь будет не отличить от error.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
SysFn62.4(|5|6):ReadPCIByte(|Word|Dword)
0CodErr
FFFFFFFF - это дефолтное состояние по стандарту PCI.
Так что если ты прочитал -1 из стандартного регистра, то он либо неинициализирован, либо обращение было направлено к пустому слоту.
FFFFFFFF - это дефолтное состояние по стандарту PCI.
Так что если ты прочитал -1 из стандартного регистра, то он либо неинициализирован, либо обращение было направлено к пустому слоту.
Евангелие от Иоанна: стих 1[/size]
Code: Select all
; В начале было Слово:
B32: mov ax, os_stack ; Selector for os
art_zh, спасибо, теперь понятно, почему так.
Я делаю обёртки для своей 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;
(* -------------------------------------------------------- *)
Если паскаль сохраняет используемые регистры, то почти все ОК.
x86 calling convention - AX, CX, DX внутри функций свободно применимы, остальные надо сохранять.
Только не используй Byte в параметрах - только 32-битные параметры.
x86 calling convention - AX, CX, DX внутри функций свободно применимы, остальные надо сохранять.
Только не используй Byte в параметрах - только 32-битные параметры.
Siemargl, я по возможности придерживаюсь этого. Но иногда из-за этого пришлось бы делать дополнительные преобразования. С другой стороны, сам вызов int 64 гораздо медленнее.Только не используй Byte в параметрах - только 32-битные параметры.
Ну я согласно документации делаю:Если паскаль сохраняет используемые регистры, то почти все ОК.
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;
Точно так же ReadPCIByte возвращает байт, что логично, потому что именно байт читали.
Проверь, что именно компилятор засовывает в стек. Нужно 32-битное значение (даже если данные там в младшем байте). Иначе будет невозможно нормально вызывать твои функции.0CodErr wrote:Если было бы не Byte, а Dword, то программист мог бы по ошибке передать значение, выходящее за пределы диапазона Byte, а компилятор промолчал бы. Я считаю, что здесь использование Byte вполне оправдано.
Точно так же ReadPCIByte возвращает байт, что логично, потому что именно байт читали.
Ну и к интероперабельности - строки только asciiz, структуры (record) с явным выравниванием (или без), выделенная память передаваемая - только через сисфункции.
Siemargl, у меня из 260-ти функций только в 50-ти используется Byte, а в остальных Dword\Pointer.
Я проверил, что делает компилятор, перед вызовом функции он делает примерно такТо есть, на стеке всё равно будет Dword.
Ну и, естественно, что, поскольку функции StdCall, то и использоваться могут не только из Delphi\FreePascal, но и из любого другого, поддерживающего такое соглашение вызова(а его все поддерживают, насколько знаю).
Я проверил, что делает компилятор, перед вызовом функции он делает примерно так
Code: Select all
00000022: 8A 04 24 mov al,byte ptr [esp]
00000025: 50 push eax
Это уже всё согласно документации к системным функциям KolibriOS.Ну и к интероперабельности - строки только asciiz, структуры (record) с явным выравниванием (или без), выделенная память передаваемая - только через сисфункции.
Ну и, естественно, что, поскольку функции StdCall, то и использоваться могут не только из Delphi\FreePascal, но и из любого другого, поддерживающего такое соглашение вызова(а его все поддерживают, насколько знаю).
Хорошо, но желательно чтобы он делал0CodErr wrote:Siemargl, у меня из 260-ти функций только в 50-ти используется Byte, а в остальных Dword\Pointer.
Я проверил, что делает компилятор, перед вызовом функции он делает примерно такТо есть, на стеке всё равно будет Dword.Code: Select all
00000022: 8A 04 24 mov al,byte ptr [esp] 00000025: 50 push eax
movzx al,byte ptr [esp]
А то в старших байтах будет мусор
Не-не, тут ты не прав, нет такой команды просто.Siemargl wrote:Хорошо, но желательно чтобы он делал
movzx al,byte ptr [esp]
Если ты имел в виду movzx eax, то я думаю, что компилятор наверняка следит за использованием регистров.
Ну и что с того?А то в старших байтах будет мусор
Например, вызываем
Code: Select all
Var MyByte: Byte;
MyByte := ReadPCIByte(Bus, Device, Func, Reg);
Более того, под номер функции устройства отводится всего 3 бита.
Так что, можно даже не байт использовать, а определить
Code: Select all
Type TThreeBits = 0..7;
Code: Select all
Func: TThreeBits
Constant expression violates subrange bounds
прости, проблемы паскаля меня мало волнуют - ты приводишь примеры, которые разбирает компилятор
а я про более низкоуровневый код
вот тебе несуществующая инструкция
http://x86.renejeschke.de/html/file_mod ... d_209.html
а я про более низкоуровневый код
вот тебе несуществующая инструкция
http://x86.renejeschke.de/html/file_mod ... d_209.html
Не знаю уж, что я там должен был найти, может и плохо искал, конечно. Но вот тебе из мануалаSiemargl wrote:вот тебе несуществующая инструкция
http://x86.renejeschke.de/html/file_mod ... d_209.html
Spoiler:
0CodErr
Code: Select all
movzx eax, byte ptr [esp]
push eax
brunnel, yes, i noticed Siemargl about it in the post above.
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.
But it seems that Siemargl think that the compiler was made by stupid people who can not in the basic things.Если ты имел в виду movzx eax, то я думаю, что компилятор наверняка следит за использованием регистров.
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.
Who is online
Users browsing this forum: No registered users and 1 guest