2013-03-22 55 views
1

我有一个简单的程序,它必须读取PCI configuration space(仅适用于第一个PCI设备)。但它不起作用。 YASM: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 

感谢。

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

回答

3

不能使用带有16位立即端口号的outin。对于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作为内存的索引,在哪里存储内容。但是由于您没有为此预留任何内存,因此您可以从端口0xcf8(如果您首先修复了即时的16位端口号)快速覆盖mov ax,0xb80066 b8 00 b8,正好为4个字节),并将值读取到eax

其次,我不完全知道从哪里es点在默认情况下Bootloader代码,无论如何,它可能有必要与第一设置:

 
push cs 
pop es 

保留内存:

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

但这仍然不够。如果要将从0xcfc读取的数字打印到eaxrep 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,它有两种不同的方式来做它的示例代码。

希望这会有所帮助。

+0

谢谢。但程序不做任何事情(它确实清除了检查的屏幕)。是所有'输入/输出'操作还是只需要32位(如'eax'等)? – Vanzef 2013-03-22 16:06:49

+0

@Vanzef在您的代码中添加了更多问题的解释。 ['in'](http://web.itu.edu.tr/kesgin/mul06/intel/instr/in.html)和['out'](http://web.itu.edu.tr/kesgin /mul06/intel/instr/out.html)只允许8位直接端口地址,而'al','ax'和'eax'则是一样的。对于16位端口地址,必须使用'dx'。 – nrz 2013-03-22 16:34:39

+0

...而且你不想要“32位”! – 2013-03-22 17:56:20