setvect : Fatal: Cannot generate COM file : segment-relocatable items present
-
Ich brauche setvect() in einem .com-File (nicht .exe!).
Mit BCC -mt -lt test.c und tlink -t c0t test.obj, test.com,, cs /c:\bc\lib
erhalte ich aber eben immer
"Fatal: Cannot generate COM file : segment-relocatable items present"
Verwende ich um setvect() zu ersetzen (famd ich im Netz):{ void* int_v; int_v=newserialint; asm push es asm push bx // ES=0 -> Zeiger auf interrupt vector tabelle bei 0:0 asm xor bx,bx asm mov es,bx asm mov bx,12 // 12=Interruptnummer (hier serielle Schnittstelle) asm shl bx,1 // mal 4 wegen 4 Byte Länge der far-Addresse des Interrupts) asm shl bx,1 asm pushf asm cli asm mov ax,word ptr [int_v] asm mov es:[bx],ax asm mov ax,word ptr [int_v+2] asm mov es:[bx+2],ax asm popf asm pop bx asm pop es asm sti }
,
so stürzt das Programm bei Interruptauslösung leider ab (mit setvect als exe geht's aber ja).
Was mache ich nur? Brauche professionelle Hilfe...Edit by AJ: CPP-Tags eingefügt; das nächste mal bitte selber dran denken!
-
Schau mal was man in Google: segment-relocatable items present so alles findet:
-
AJ schrieb:
Schau mal was man in Google: segment-relocatable items present so alles findet:http://www.google.de/url?sa=U&start=1&q=http://www.vmlinux.org/~jakov/community.borland.com/16623.html&e=10342
Den Artikel hatte ich mir zwar auch schon einmal ergoogelt, hatte aber bisher noch kein Listfile erzeugt, da ich davon ausging, daß ich setvect ja eh nicht verwenden kann und auch kein Assembler (richtig) kann.
Im Falle von setvect erhalte ich neben den mir nichts sagenden Ausdrücken wie
504 extrn _setvect:near
und
_PRINTF Near ----:---- Extern
_SETVECT Near ----:---- Extern
an der Stelle des Opcodes für setvect:
171 008E B8 0000s mov ax,seg _newserialint
172 0091 50 push ax
173 0092 B8 015Er mov ax,offset _newserialint
174 0095 50 push ax
175 0096 B8 000C mov ax,12
176 0099 50 push ax
177 009A E8 0000e call near ptr _setvect
178 009D 83 C4 06 add sp,6Der neue Interrupt wird ja sicher in einem anderen Segment liegen, aber wie kann ich das in's com.File bekommen?
(Das Problem ist hier wohl vor allem auch das Wort “interrupt“, dessen Typ an setvect übergeben wird.)
-
Welche Headerdatei nimmst du eigentlich für setvect() her.
Ich kenne die Funktion leider nicht
-
setvect ist in dos.h und unter BC3.1 eigentlich die einzige Möglichkeit, einen neuen Interrupt zu installieren. Leider alles mit dem problematischen "interrupt", daß ich schon mal durch
void newint(void){ asm pushf; asm push ax; asm push bx; asm push cx; asm push dx; asm push es; asm push ds; asm push si; asm push di; asm push bp; .... asm pop bp; asm pop di; asm pop si; asm pop ds; asm pop es; asm pop dx; asm pop cx; asm pop bx; asm pop ax; asm popf; asm iret; };
zu ersetzen versucht habe, was aber auch nur Abstürze erzeugt.
Hab' jetzt erst mal WE. Melde mich Dienstag mit neuen Experimenten dazu...
-
Ich glaube ich hatte damit doch schon mal zu schaffen (oder besser gesagt einer ähnlichen Funktion)
Schau dir mal das hier in der FAQ an:
Das müsste dir eigentlich weiterhelfen
-
Werde mir das mit void __interrupt __far und _dos_setvect() mal ansehen und herumprobieren. Als Exe geht's ja (war das denn damals auch als .com-File gedacht? Hintergrund ist ein Device-Treiber, den ich schreiben muß und worin der Interrupt ersetzt werden muß...)
-
Nein das war auch ein Teil einer EXE, aber probiers trotzdem mal aus. Dieser Code macht im Endeffekt auch nichts anderes als einen Interrupt zu ersetzen.
Möglicherweise hat das mit deinem Assamblercode nicht funktioniert, weil du vorher nicht die Interrupts ausgeschaltet hast. Das ist nämlich sehr wichtig, wenn man im Interrupt-Vector rumdoktort! Danach muss man die Interrupts natürlich wieder einschalten ;).
-
user4711 schrieb:
an der Stelle des Opcodes für setvect:
171 008E B8 0000s mov ax,seg _newserialint
172 0091 50 push axWenn du das beides irgendwie durch ein push cs ersetzen könntest, wär alles in Butter. Ich tipp mal, dass deine newserialint-Prozedur far deklariert ist, sonst würde der Compiler nicht auf die Idee kommen, das Segment zu bestimmen.
-
Das Problem fängt jetzt offenbar schon sehr früh bei mir an.
Wenn ich mein Programm compiliere (es möge hier mal test.c heißen) mache ich das um setvect samt Segmenten in Assembler zu beobachten mit der Erzeugung eines ASM-Files für TASM:BCC -S test.c
TASM test.asmwenn ich aber dann linken will, erhalte ich mit
tlink -ms -ls c0s test.obj, test.exe,, cs /c:\bc\libTurbo Link Version 5.1 Copyright (c) 1992 Borland International
Error: Undefined symbol _main in module c0.ASM
Error: Undefined symbol _PRINTF in module RS485.C
Error: Undefined symbol __DOS_SETVECT in module RS485.C
Error: Undefined symbol _KBHIT in module RS485.C
Error: Undefined symbol _GETCH in module RS485.C
Error: Undefined symbol _DELAY in module RS485.CWenn ich mit BCC direkt eine exe erzeuge geht das mit BCC -ms -ls test.c
wunderbar.Aber was muß ich bei Tlink beachten, um ein Ergebnis zu bekommen???
-
P.S.: Hab's versehentlich nicht rauseditiert: Das File heißt also im Original nicht test.c sondern rs485.c und soll den Interupt 12 ersetzen ...