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!





  • 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,6

    Der 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:

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-45173-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html

    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 ax

    Wenn 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.asm

    wenn ich aber dann linken will, erhalte ich mit
    tlink -ms -ls c0s test.obj, test.exe,, cs /c:\bc\lib

    Turbo 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.C

    Wenn 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 ...


Anmelden zum Antworten