Page 1 of 1

Calling BIOS service via far call

Posted: Mon Dec 03, 2007 8:47 am
by devel
Hi there,

how to call BIOS service via far call i.e. not via interrupt call in real mode?
An example would be very helpful.

thnx in advance,
devel.

Posted: Mon Dec 03, 2007 9:17 am
by JamesM
You can't do it. You have to be in real mode or running a v8086 task.

Posted: Mon Dec 03, 2007 9:29 am
by devel
Ok, so let me be clear with that. So if processor is in real mode is possible to call BIOS service via far call?
Looking into intel's manual 2A, instruction 'int n' you can read this:
The action of the INT n instruction (including the INTO and INT 3 instructions) is similar to that of a far call made with the CALL instruction. The primary difference is that with the INT n instruction, the EFLAGS register is pushed onto the stack before the return address.


So I think it should be somehow possible or am I wrong?

regards,
devel.

Posted: Mon Dec 03, 2007 9:36 am
by AJ
If you want to do it in real mode (the only reason I can see you would need to do this is if you are writing a VMM), you can do it by reading the seg:offset pair from the IVT (which is at 0x0000:0x0000).

If you have Intel's manuals, look up about the IVT.

Cheers,
Adam

Posted: Tue Dec 04, 2007 10:12 am
by devel
Hi there,

I am trying to call a BIOS vga service in the following way please correct me if I am wrong ...

1. The following structure is defined as representative of a far pointer:

Code: Select all

typedef struct {
  uint32_t off32;       /* lsb */
  uint16_t seg16;       /* msb */
} bioscall_vector_t;
2. I would like to call vga service which should be 0x10's entry in IVT. So I
assume if each entry is 4byte long the service shall be at address (offset in
code segemnt 0x0000) 0x10*4 = 0x40 (ok???). Mentioned vector in my c file
has following values:

Code: Select all

__ATTR(aligned(1)) bioscall_vector_t __bios_vectorcall =
{
  .off32        = 0x00000040, // vga service * 4 = offset 
  .seg16        = 0x0000,      // code segment
};
3. Then in my assembly code I fill all registers with appropriate values and perform call:
note: this is a gas syntax

Code: Select all

  .code16gcc
  ...
  movw $0x0007,%bx               /* char's attribute */
  movb $0xe,%ah                    /* bios function: write char */
  movb $'0',%al                       /* char to print */
  lcall *__bios_vectorcall           /* perform indirect call */
  ...
After all I should see a character '0' on the screen ... but nothing happens :(.
FYI, the code is running in real mod, using a qemu soft.

thnx in advance & regards,
devel