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.