PCI设备检查汇编语言

时间:2013-03-22 15:59:04

标签: assembly x86 bootloader pci yasm

我有一个简单的程序,必须阅读PCI configuration space(仅适用于第一个PCI设备)。但它不起作用。 YASM:

18: warning: value doesnt fit in 8 bit fild
19: warning: value doesnt fit in 8 bit fild

以下是代码:

   [use    32]
    [org    0x7c00]

start:
    mov     ah, 0x3
    int     0x10        ;clear screen
;forming the PCI address

    push    ax
    or      ah, 10000000b
    xor     al, al
    or      al, 00000001b
    shl     eax, 16
    pop     ax
    xor     al, al
    xor     ah, ah
    push    eax
    out     0xcf8, eax
    in      eax, 0xcfc
    mov     edi, field
    stosd   
    mov     si, di
    call    print_str
    ret
field:      
print_str:
;print a string in si
    mov     ax, 0xb800
    mov     es, ax
    xor     di, di
    mov     cx, 128
    rep     movsw
    ret

    times   510 - ($ - $$) db 0
    dw      0xaa55

感谢。

P.S。我正在使用Bochs进行仿真,使用YASM作为汇编程序

1 个答案:

答案 0 :(得分:3)

您不能将outin与16位立即端口号一起使用。 inout只能使用8位立即端口号。

因此您需要将端口号存储到dx

mov     dx,0xcf8
out     dx,eax
in      eax,dx

然后,在下面的块中有几个问题:

mov     edi,field
stosd
mov     si, di
call    print_str
ret
field:      
print_str:
;print a string in si
mov     ax, 0xb800
mov     es, ax
xor     di, di
mov     cx, 128
rep     movsw
ret

编辑:修正了拼写错误,应该是:“不要保留”。校正。

上面的块有几个问题。首先,我假设你想使用edi作为内存的索引,在哪里存储东西。但是,由于您没有为此目的保留任何内存,因此您很高兴使用从端口mov ax,0xb800读取到66 b8 00 b8的值覆盖eax0xcf8,正好为4个字节) (如果您首先修复了直接的16位端口号。)

其次,我不确定在引导加载程序代码中默认指向es的位置,无论如何,可能需要先将其设置为:

push cs
pop  es

保留记忆:

field:
times 4 db 0 ; to reserve 4 bytes (but you may need more,
             ; keep reading to understand why)

但这仍然不够。如果您要将0xcfc中的数字打印到eax rep movsw,您需要先将其转换为字符串。将数字转换为x86程序集中的字符串(十进制或十六进制)在SO中经常被问到,所以请检查一些以前的答案以获得想法:

Is this code correct (Number plus number, then print the result)

请注意,您需要的字节数与数字中的字符数一样多,如果您想使用rep movsw,则需要2 x字符数。(参见下文)。

然后在用于写入视频内存的代码中,您似乎将二进制值复制到视频内存而不进行任何转换。因此,在完成上述2个修复后,您可能会在第一行的前64个字符中获得一些彩色字符。请参阅my recent answer to a SO question on printing a string without OS,它有示例代码,有两种不同的方法。

希望这有帮助。