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.