如何通过pci功能id识别设备?这是我的代码:
我尝试访问34h并检查第一个循环中是否存在能力id如果它存在,它会指向下一个指针,但在获取指针和放置地址的步骤中似乎存在一些问题。
''
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
''
编写此答案时假设此代码正在寻找PCI Express功能。
此代码中存在几个问题。
- 在
first
标签处,应使用al
而不是ah
来确定第一个功能的偏移量 - PCI Express功能的功能ID是10h,而不是10
- 在读取每个能力头之后,
al
包含能力id,ah
包含下一个指针。所以cmp ah, 10
应该是cmp al, 10h
- 在
nextreg
标签处,它应该使用ah
而不是al
来确定下一个能力的偏移量 - 在每次迭代中,它将
bx
添加到di
,而不删除先前的偏移 - 目前还不清楚
edi
被初始化为什么,但如果它没有设置位31,那么这个代码根本不会读取PCI配置空间
这应该有效:
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:
更好的方法是将原始地址保留在
edi
中而不更改,并对每个新偏移使用lea eax, [edi+ebx]
。不需要使用
ecx
作为循环计数器,而且逻辑有点复杂。它可以稍微拉直一点,流得更清楚。
以下是我的写作方式:
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:
(我不知道set_cur
和regmem
是什么,所以我没有试图写这部分代码。(