I am calling a procedure from a C++ program, the procedure is located in an obj file which was compiled from a assembler code. Anyway, the asm procedure contains interrupts such as int 21h. The assembler program runs perfectly fine on its own, but when i link to it from C++ and call the procedure from C++, the program crashes at run time, and this is caused by the interrupts, since if i remove the interrupts from the assembler procedure, everything works.
So my question is, how do i run an assembler procedure which contains interrupts from C++?
BTW, im using WinXP if it matters to the answer.
Posted on 2003-03-06 03:09:31 by osushkov
Maybe it has something to do with the C Runtime libs. Try excluding them from your project.
Posted on 2003-03-06 03:14:52 by iblis
ASM code containing INT 21h requires a DOS environment. You won't get that by linking to a Win32 C++ compiler. You need a C++ compiler and linker package that can generate code for DOS.
Posted on 2003-03-06 04:37:26 by tenkey
Yes, ints are not allowed while running in windows.
Posted on 2003-03-06 11:51:50 by drhowarddrfine
You may get away with INTs on 9x systems, but not on NT (XP) based systems. :)
Posted on 2003-03-06 12:10:16 by S/390
Yes, you can call DOS functions, but you must call them from a 16-bit segment using a 16-bit stack. To do so from a Win32 program, you must use the secret functions 35, 36 and 37 in KERNEL32. They work like LoadLibrary, FreeLibrary and GetProcAddress but are for 16-bit DLLs. Use this to get the address of AllocSelector, FreeSelector, SetSelectorBase and PrestoChangoSelector from KERNEL. You then call QT_Thunk with the address in EDX and a pointer to the end of a 64-byte area in EBP. Call AllocSelector to allocate a new selector. Then use PrestoChangoSelector to set it up, using [+0x124] as the parameter. Call SetSelectorBase with the address of your function, and call it the same way. Then, free the selector with FreeSelector. And remember, the Win16 functions have the parameters backwards compared to the Win32 functions. Oh, and this will most likely not work in NT.

Example (for NASM):
IMPORT LL16 kernel32 35
IMPORT GPA16 kernel32 37
IMPORT QT_Thunk kernel32
bits 32
push dword kdll
mov ,eax
push dword allocsel
push eax
mov edx,eax
mov ebp,esp
sub esp,64
push word 0
mov ,ax
mov esi,
push word
push ax
push dword changesel
push dword
mov edx,eax
push dword setselbase
push dword
mov edx,eax
push word
push dword c16proc
push dword freesel
push dword
mov edx,eax
push word
kdll db "KERNEL",0
allocsel db "AllocSelector",0
freesel db "FreeSelector",0
setselbase db "SetSelectorBase",0
changesel db "PrestoChangoSelector",0
bits 16
; you can use int 0x21 here. Most of the functions work like int 0x21 in DOS, but functions that take pointers expect protected mode pointers.
; You can also call DPMI functions. This can be used, for example, to call DOS TSRs or use the MSCDEX interface.
Posted on 2003-03-06 14:46:55 by Sephiroth3
I didn't think interrupts worked either until somebody showed me this.

Posted on 2003-03-06 16:56:28 by iblis
Well, ain't that a kick in the head! I never saw those before. I mean under win programming. Were these abilities always available under windows? Or are these those secret, hidden functions all the other companies were upset about?
Posted on 2003-03-06 18:28:59 by drhowarddrfine
most interesting interrupts (21h, 13h, 25h) are available in Win9x systems through opening "VWIN32" and then do DeviceIOControl function. and this is documented. If the interrupt you are interested in is not supported, you may use a "flat thunk" (thats fully documented too), which requires writing a 32bit dll and a 16-bit dll counterpart. But remember, both methods for win9x systems only!

Posted on 2003-03-07 02:03:45 by japheth