How to identify the device by pci capability id? this is my code:
I try to access 34h and check if the capability id exists on the first loop If it exists, it points to the next pointer, But there seems to be some problems in the steps of getting the pointer and putting the address.
'''
push eax
push edi
push esi
mov cx,100
;mov edi,[esi]
add edi,52 ;access 34h
lopreg:
mov eax,edi ;read
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx
cmp cx,100 ;first time
je first
cmp ah,10
jne nextreg
jmp ispcie
first:
cmp ah,0
je ending
sub edi,52
movzx bx,ah
add di,bx
loop lopreg
jmp ending
ispcie:
call set_cur
mov ah,09h
lea dx,regmem ;print pcie
int 21h
jmp ending
nextreg:
cmp al,0
je ending
movzx bx,al ;
add di,bx
loop lopreg
ending:
pop esi
pop edi
pop eax
ret
'''
This answer is written with the assumption that this code is looking for the PCI Express Capability.
There are several problems in this code.
first
label, it should use al
instead of ah
to determine the offset of the first capability.al
contains the capability id and ah
contains the next pointer. So cmp ah, 10
should be cmp al, 10h
.nextreg
label, it should use ah
instead of al
to determine the offset of the next capability.bx
to di
without removing the previous offset.edi
is initialized to, but if it does not have bit 31 set, then this code won't be reading PCI config space at all.This should work:
mov cx,100
;mov edi,[esi]
add edi,52 ;access 34h
lopreg:
mov eax,edi ;read
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx
cmp cx,100 ;first time
je first
cmp al,10h
jne nextreg
jmp ispcie
first:
cmp al,0
je ending
sub edi,52
movzx bx,al
add di,bx
loop lopreg
jmp ending
ispcie:
call set_cur
mov ah,09h
lea dx,regmem ;print pcie
int 21h
jmp ending
nextreg:
cmp ah,0
je ending
sub di, bx
movzx bx,ah
add di,bx
loop lopreg
ending:
A better approach is to keep the original address in edi
without changing it, and use lea eax, [edi+ebx]
for each new offset.
There's no need to use ecx
as a loop counter and the logic is a bit convoluted. It can be straightened out a bit to flow more clearly.
Here's how I would write it:
lea eax,[edi+34h]
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in al,dx ; read offset of first capability
cmp al,0
je ending
movzx ebx,al
lopreg:
lea eax,[edi+ebx] ; offset of next capability is in ebx
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx ; read capability header
cmp al,10h ; check if it is the PCI Express capability
je ispcie
nextreg:
cmp ah,0 ; check if it is the end of the capability list
je ending
movzx ebx, ah ; set up ebx with the offset of the next capability
jmp lopreg
ispcie:
; base of device PCI config space is in edi
; offset of PCI Express Capability is in ebx
...
ending:
(I don't know what set_cur
and regmem
are so I didn't attempt to write that part of the code.)