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.
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.
Maybe it has something to do with the C Runtime libs. Try excluding them from your project.
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.
Yes, ints are not allowed while running in windows.
You may get away with INTs on 9x systems, but not on NT (XP) based systems. :)
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):
EXTERN LL16
IMPORT LL16 kernel32 35
EXTERN GPA16
IMPORT GPA16 kernel32 37
EXTERN QT_Thunk
IMPORT QT_Thunk kernel32
bits 32
..start
push dword kdll
call
mov ,eax
push dword allocsel
push eax
call
mov edx,eax
mov ebp,esp
sub esp,64
push word 0
call
mov ,ax
mov esi,
push word
push ax
push dword changesel
push dword
call
mov edx,eax
call
push dword setselbase
push dword
call
mov edx,eax
push word
push dword c16proc
call
push dword freesel
push dword
call
mov edx,eax
push word
call
ret
kdll db "KERNEL",0
allocsel db "AllocSelector",0
freesel db "FreeSelector",0
setselbase db "SetSelectorBase",0
changesel db "PrestoChangoSelector",0
c16proc:
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.
retf
Example (for NASM):
EXTERN LL16
IMPORT LL16 kernel32 35
EXTERN GPA16
IMPORT GPA16 kernel32 37
EXTERN QT_Thunk
IMPORT QT_Thunk kernel32
bits 32
..start
push dword kdll
call
mov ,eax
push dword allocsel
push eax
call
mov edx,eax
mov ebp,esp
sub esp,64
push word 0
call
mov ,ax
mov esi,
push word
push ax
push dword changesel
push dword
call
mov edx,eax
call
push dword setselbase
push dword
call
mov edx,eax
push word
push dword c16proc
call
push dword freesel
push dword
call
mov edx,eax
push word
call
ret
kdll db "KERNEL",0
allocsel db "AllocSelector",0
freesel db "FreeSelector",0
setselbase db "SetSelectorBase",0
changesel db "PrestoChangoSelector",0
c16proc:
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.
retf
I didn't think interrupts worked either until somebody showed me this.
http://msdn.microsoft.com/library/en-us/win9x/95func_50j7.asp
http://msdn.microsoft.com/library/en-us/win9x/95func_50j7.asp
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?
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!
Japheth
Japheth