1

我有一个简单的程序,必须读取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

谢谢。

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

4

1 回答 1

3

您不能使用outorin与 16 位立即端口号。和 只能使用 8 位立即端口inout

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

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

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

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

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

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

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

推cs
流行音乐

要保留内存:

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

但这还不够。如果要将读取的数字打印0xcfceaxwith rep movsw,则需要先将其转换为字符串。在 x86 程序集中将数字转换为字符串(十进制或十六进制)在 SO 中经常被问到,因此请查看一些先前的答案以了解这个想法:

此代码是否正确(数字加数字,然后打印结果)

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

然后在用于写入显存的代码中,您似乎无需任何转换即可将二进制值复制到显存。因此,在完成上述 2 个修复后,您可能会在第一行的前 64 个字符中获得一些彩色字符。请参阅我最近对打印没有 OS 的字符串的 SO question 的回答,它有示例代码和两种不同的方法。

希望这可以帮助。

于 2013-03-22T16:03:46.180 回答