【问题标题】:PCI device check in assembly language汇编语言中的 PCI 设备检查
【发布时间】:2013-03-22 15:59:04
【问题描述】:

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

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

谢谢。

附:我使用 Bochs 进行仿真,使用 YASM 作为汇编程序

【问题讨论】:

    标签: assembly x86 bootloader pci yasm


    【解决方案1】:

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

    所以需要将端口号存入dx

    mov dx,0xcf8 输出 dx,eax 在 eax,dx

    那么,在下面的块中有几个问题:

    mov edi,字段 斯托德 莫西迪 调用 print_str ret 场地: 打印字符串: ; 在 si 中打印一个字符串 移动斧头,0xb800 移动,斧头 异或迪 mov cx, 128 代表 movsw ret

    编辑:修正了错字,应该是:“不要保留”。已更正。

    上面的块有几个问题。首先,我假设您想使用edi 作为内存索引,用于存储某些内容。但是由于您没有为此目的保留任何内存,因此您很乐意用您从端口 0xcf8 读取到 eax 的值覆盖 mov ax,0xb80066 b8 00 b8,正好 4 个字节)(如果您首先修复了直接的 16 -bit 端口号)。

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

    推cs 流行音乐

    要保留内存:

    场地: 乘以 4 分贝 0 ;保留 4 个字节(但您可能需要更多, ;继续阅读以了解原因)

    但这还不够。如果要将0xcfc读取的数字用rep movsw打印成eax,需要先转换成字符串。在 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,它有示例代码,有两种不同的方法。

    希望这会有所帮助。

    【讨论】:

    • 谢谢。但是程序没有做任何事情(例如,它确实清除了屏幕)。是所有in/out 操作都需要还是仅用于32 位(如eax 等)?
    • @Vanzef 添加了对代码中更多问题的说明。 inout 只允许 8 位直接端口地址,alaxeax 也是如此。对于 16 位端口地址,必须使用 dx
    • ...你不想bits 32
    猜你喜欢
    • 2013-06-21
    • 2023-03-23
    • 1970-01-01
    • 2014-12-14
    • 2010-12-24
    • 2011-05-03
    • 2014-10-07
    • 1970-01-01
    相关资源
    最近更新 更多