EXTERN FAR - Error



  • Hallo, weder Google noch die Zeit konnten mir helfen.

    Ich habe zwei ASM Dateien, eine davon stellt eine Funktion zur Verfügung, welche von dem Hauptprogramm genutzt wird. Jetzt möchte ich beide Dateien in Obj-Dateien verwandeln und danach zusammen linken.
    Ich benutze MASM32 (ml.exe, link.exe), 32bit, Win7 x64.

    Die Programme sind folgendermaßen aufgebaut:

    Funktion:

    .586
    .MODEL flat, stdcall
    OPTION casemap:none
    
    INCLUDELIB	C:\masm32\lib\user32.lib
    ...
    .DATA
    ...
    .CODE
    PUBLIC Function
    Function PROC FAR
    push EBP
    mov  EBP, ESP
    ...
    mov ESP, EBP
    pop EBP
    retf
    Function ENDP
    END
    

    Programm:

    .586
    .MODEL flat, stdcall
    OPTION CASEMAP :NONE
    
    INCLUDELIB	C:\masm32\lib\user32.lib
    ...
    EXTERN StringToInteger : FAR ;*
    ...
    .CODE
    ...
    call Function
    ...
    

    Folgender Fehler tritt auf:
    "error A2004: symbol type conflict"
    Wenn ich FAR in NEAR ändere, passiert folgendes:
    "fatal error LNK1120: 1 unresolved externals"
    Dann habe ich probehalber EXTERN bzw EXTRN gelöscht und es mit "PROTO Function" versucht. Ließ sich starten, allerdings gab es beim Funktionsaufruf direkt den Crash...

    ml.exe /c /coff Function.asm
    ml.exe /c /coff Main.asm
    link.exe Main Function /entry:Start /subsystem:windows

    Wo liegt mein Fehler?

    MfG



  • - deklarier deine Funktion in Beiden Dateien mittels PROTO
    - NEAR und FAR haben in ring3 Applikation nichts zu suchen (alles ist NEAR, da es nur 'ein' Segment gibt)
    - den Stackframe brauchst du nicht explizit zu schreiben - dieser wird automatisch durch die PROC-Direktive erstellt (sofern nicht deaktiviert). Außerdem: RETF -> RET.
    - am Ende des Hauptprogramms: END labelEintrittspunkt
    - benutz die Includes, die mit dem MASM32-package kommen

    main:

    include masm32rt.inc
    
    SomeFunction proto pChar: ptr CHAR
    
    .code
    main proc
    
    	invoke SomeFunction,chr$("123 abc",13,10)
    
    	inkey
    	exit
    
    main endp
    end main
    

    Modul:

    include masm32rt.inc
    SomeFunction proto pChar: ptr CHAR
    .code
    SomeFunction proc pChar: ptr CHAR
    
    	print pChar
    
    	ret
    
    SomeFunction endp
    end
    

    Build:

    ml /c /coff /Cp "module.asm"
    ml /c /coff /Cp "main.asm"
    link /SUBSYSTEM:CONSOLE /RELEASE /OUT:"main.exe" "main.obj" "module.obj"
    


  • Klasse, danke dir!

    Wie müsste das denn aussehen, wenn ich nicht die MASM32 Macros benutzen würde, sprich PROC, PROTO, NEAR, FAR, etc. ?
    Und wann benutze ich NEAR, bzw. FAR ?

    Nur wenn es kein zu großer Aufwand ist...

    MfG



  • Wie gesagt, in Win32-Anwednugen (user mode), ist alles NEAR - normaler weise muss man dies nicht explizit Angeben - außer man verzichtet auf PROC.
    Funktionen deklariert man grundsätzlich mittels PROTO. Für die Beschreibung der Funktion benutzt man PROC. Wenn du unbedingt Variablen in mehrere Modulen benutzen willst, dann benutz EXTERNDEF label:type (z.B. EXTERDEF myVar:DWORD). Diese Deklaration kannst du in eine Include packen und anschließend in alle Module verwenden - das gleich gilt im Übrigen auch für PROTO's.

    include masm32rt.inc
    ; SomeFunction verhält sich wie eine StdCall-Funktion
    EXTERNDEF SomeFunction: NEAR
    
    .data
    	myStr db "123 abc",13,10,0
    .code
    main proc
    
    	; lea eax,myStr
    	; push eax
    	push OFFSET myStr
    	call SomeFunction
    
    	inkey
    	exit
    
    main endp
    end main
    
    include masm32rt.inc
    EXTERNDEF SomeFunction: NEAR
    .code
    SomeFunction:
    	push ebp
    	mov ebp,esp
    
    	print DWORD ptr [ebp+8]
    
    	mov esp,ebp
    	pop ebp	
    	retn 4			; return NEAR , 4 => DWORD = pChar
    end
    


  • andere Syntax, ohne NEAR:

    include masm32rt.inc
    EXTERNDEF SomeFunction: PROC
    .code
    SomeFunction:
    	push ebp
    	mov ebp,esp
    
    	print DWORD ptr [ebp+8]
    
    	mov esp,ebp
    	pop ebp	
    	ret 4			; return NEAR , 4 => DWORD = pChar
    end
    


  • Ah okay, danke !

    Dann entsprechen PROC und ENDP eigentlich nur

    push EBP
    mov EBP, ESP
    

    bzw.

    mov ESP, EBP
    pop EBP
    

    ?

    In welchem Fall würden man denn ein FAR setzen müssen?


Anmelden zum Antworten