I have a simple program, that must read PCI configuration space
(just for first PCI device). But it doesnt works.
YASM:
18: warning: value doesnt fit in 8 bit fild
19: warning: value doesnt fit in 8 bit fild
Here is the code:
[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
Thanks.
P.S. I'm using Bochs for emulation and YASM as assembler
You can't use out
or in
with 16-bit immediate port numbers. Only 8-bit immediate port numbers are possible for in
and out
.
So you need to store the port number into dx
:
mov dx,0xcf8 out dx,eax in eax,dx
Then, in the block below there are several issues:
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
Edit: Fixed typo, should be: "don't reserve". Corrected.
The block above has several problems. First, I assume you want to use edi
as an index to memory, where to store something. But as you don't reserve any memory for that purpose, you happily overwrite mov ax,0xb800
(66 b8 00 b8
, exactly 4 bytes) with the value you read to eax
from port 0xcf8
(if you first fixed the immediate 16-bit port numbers).
Second, I'm not exactly sure where es
points by default in bootloader code, anyway, it may be necessary to set it first with:
push cs pop es
To reserve memory:
field: times 4 db 0 ; to reserve 4 bytes (but you may need more, ; keep reading to understand why)
But this is still not enough. If you want to print the number read from 0xcfc
into eax
with rep movsw
, you need to first convert it into a string. Converting a number into a string in x86 assembly (either decimal or hexadecimal) is quite frequently asked in SO, so check some previous answers to get the idea:
Is this code correct (Number plus number, then print the result)
Note that you'll need as many bytes as there are characters in the number, or 2 x number of characters if you want to use rep movsw
(see below).
Then in the code used to write to video memory, you seem to copy binary values to video memory without any conversion. So after doing the above 2 fixes, you would probably get some colored characters in the first 64 characters of the first row. See my recent answer to a SO question on printing a string without OS, it has example code with 2 different ways to do it.
Hope this helps.