Calling BIOS service via far call

Programming, for all ages and all languages.
Post Reply
User avatar
devel
Member
Member
Posts: 62
Joined: Wed Nov 28, 2007 4:15 am
Contact:

Calling BIOS service via far call

Post 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.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

You can't do it. You have to be in real mode or running a v8086 task.
User avatar
devel
Member
Member
Posts: 62
Joined: Wed Nov 28, 2007 4:15 am
Contact:

Post 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.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post 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
User avatar
devel
Member
Member
Posts: 62
Joined: Wed Nov 28, 2007 4:15 am
Contact:

Post 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
Post Reply