Code:
typedef unsigned char BYTE;
#ifdef _BITS16_
typedef unsigned int WORD;
typedef unsigned long DWORD;
typedef double QWORD;
#elseif
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned long QWORD;
#endif
struct byteregs
{
BYTE ah;
BYTE al;
BYTE bh;
BYTE bl;
BYTE ch;
BYTE cl;
BYTE dh;
BYTE dl;
};
struct wordregs
{
WORD ax;
WORD bx;
WORD cx;
WORD dx;
WORD bp;
WORD sp;
WORD si;
WORD di;
};
struct dwordregs
{
DWORD eax;
DWORD ebx;
DWORD ecx;
DWORD edx;
DWORD ebp;
DWORD esp;
DWORD edi;
DWORD esi;
};
struct REGS
{
byteregs h;
wordregs x; //not really used
dwordregs ex;
};
struct SREGS
{
DWORD ds;
DWORD es;
DWORD gs;
DWORD fs;
};
void int86(int interruptnum,REGS input,REGS output)
{
DWORD r_eax=input.ex.eax;
DWORD r_ebx=input.ex.ebx;
DWORD r_ecx=input.ex.ecx;
DWORD r_edx=input.ex.edx;
DWORD r_ebp=input.ex.ebp;
DWORD r_esp=input.ex.esp;
DWORD r_edi=input.ex.edi;
DWORD r_esi=input.ex.esi;
asm {
mov eax,[r_eax]
mov ebx,[r_ebx]
mov ecx,[r_ecx]
mov edx,[r_edx]
mov ebp,[r_ebp]
mov esp,[r_esp]
mov edi,[r_edi]
mov esi,[r_esi]
int [interruptnum]
mov [r_eax],eax
mov [r_ebx],ebx
mov [r_ecx],ecx
mov [r_edx],edx
mov [r_ebp],ebp
mov [r_esp],esp
mov [r_edi],edi
}
output.ex.eax=r_eax;
output.ex.ebx=r_ebx;
output.ex.ecx=r_ecx;
output.ex.edx=r_edx;
output.ex.ebp=r_ebp;
output.ex.esp=r_esp;
output.ex.edi=r_edi;
output.ex.esi=r_esi;
}
void int86(int interruptnum,REGS input,REGS output,SREGS sinput,SREGS soutput)
{
DWORD r_eax=input.ex.eax;
DWORD r_ebx=input.ex.ebx;
DWORD r_ecx=input.ex.ecx;
DWORD r_edx=input.ex.edx;
DWORD r_ebp=input.ex.ebp;
DWORD r_esp=input.ex.esp;
DWORD r_edi=input.ex.edi;
DWORD r_esi=input.ex.esi;
DWORD sr_ds=sinput.ds;
DWORD sr_es=sinput.es;
DWORD sr_fs=sinput.fs;
DWORD sr_gs=sinput.gs;
asm {
push ds
mov eax,[sr_ds]
mov ds,eax
mov eax,[sr_es]
mov es,eax
mov eax,[sr_fs]
mov fs,eax
mov eax,[sr_gs]
mov gs,eax
mov eax,[r_eax]
mov ebx,[r_ebx]
mov ecx,[r_ecx]
mov edx,[r_edx]
mov ebp,[r_ebp]
mov esp,[r_esp]
mov edi,[r_edi]
mov esi,[r_esi]
int [interruptnum]
mov [r_eax],eax
mov [r_ebx],ebx
mov [r_ecx],ecx
mov [r_edx],edx
mov [r_ebp],ebp
mov [r_esp],esp
mov [r_edi],edi
mov [sr_ds],ds
mov [sr_es],es
mov [sr_fs],fs
mov [sr_gs],gs
pop ds
}
output.ex.eax=r_eax;
output.ex.ebx=r_ebx;
output.ex.ecx=r_ecx;
output.ex.edx=r_edx;
output.ex.ebp=r_ebp;
output.ex.esp=r_esp;
output.ex.edi=r_edi;
output.ex.esi=r_esi;
soutput.ds=sr_ds;
soutput.es=sr_es;
soutput.fs=sr_fs;
soutput.gs=sr_gs;
}
Some inline assemblers do not allow the use of 32-bit registers even though they allow 32-bit code. Also some inline assemblers do not allow access to the fs and gs segment registers even though they are valid segment registers.