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:windowsWo 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 kommenmain:
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?