Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: lonx am 26. January 2010, 20:55
-
Nabend,
ich bin nun dabei mich ein bisschen in das Thema OS-Dev einzuarbeiten. Ich habe schon längere Zeit den MinGW Compiler auf dem Rechner und probierte spaßeshalber direkt mal die Beispielsourcen von
http://lowlevel.brainsware.org/wiki/index.php/Teil_2_-_Assembler_101
zu compilen. Ich bekomme immer diesen Linker-Error:
src\main.o:main.c:(.text+0x20): undefined reference to `factorial'
collect2: ld returned 1 exit status
Build error occurred, build is stopped
Ich habe schon sämtliche Varianten ausprobiert die Sourcen zu kompilieren, jedoch ohne Erfolg. Ich hab meinen MinGW komplett deinstalliert und den im Tutorial angegebenen Crosscompiler verwendet => selber Fehler. Ich bin ein ziemlich eingesessener Windows-User und bin eher bei Visual Studio heimisch, wobei es mir atm relativ schwer fällt ordentlich mit dem GCC zu arbeiten. Dazu kommt noch dass ich in Assembler noch nicht wirklich erfahren bin, da ich es bisher nie gebraucht habe (Interesse schon). Ich bin jetzt nach zwei Tagen rumtesten ziemlich ratlos und wäre sehr dankbar wenn mir aus meinen Errors helfen könnte.
MfG
-
Erstmal willkommen im Forum. :)
Du kannst mal die Objektdateien mit objdump näher anschauen (das wird in Teil 3 näher erläutert) und prüfen, welche Symbole dort benutzt werden.
Beim Stichwort Windows wäre meine erste Vermutung, dass dein C-Compiler automatisch Unterstriche vor alle Symbolnamen setzt. Du kannst das entweder abschalten, indem du dem Compiler die Option -fno-leading-underscore mitgibst, oder du gleichst es in der Assemblerdatei aus, indem du dort factorial von Hand in _factorial umbenennst.
-
:)
Mh habe ich nun ausprobiert aber geht leider auch nicht. Der Befehle dürfte ja an sich auch richtig sein laut Tutorial oder?
gcc -m32 -o factorial main.c fact.S
er erzeugt mir garkeine .o Datein (ich nehma mal an da er probiert direkt zu linken).
Ich habe es nun auch so versucht erst einzeln zu kompilieren und anschließend zu linken.
gcc -c main.c
gcc -c fact.S
ld -o factorcalc fact.o main.o
aber dann sagt er mir:
fact.o:fake:(.text+0x14): undefined reference to `factorial'
main.o:main.c:(.text+0x21): undefined reference to `_alloca'
main.o:main.c:(.text+0x26): undefined reference to `__main'
main.o:main.c:(.text+0x4f): undefined reference to `printf'
Ich nehme mal an, dass GCC nur keine Lust auf mich hat :D:(
-
Hast du das mit objdump denn mal ausprobiert? Da solltest du ziemlich eindeutig sehen, was vor sich geht. Auf jeden Fall passen die Symbole nicht zusammen, die in main.o und fact.o benutzt werden. Ich könnte an dieser Stelle nur raten, weil ich die Dateien nicht vor mir habe, aber du kannst es einfach nachschauen. ;)
main.o:main.c:(.text+0x21): undefined reference to `_alloca'
main.o:main.c:(.text+0x26): undefined reference to `__main'
main.o:main.c:(.text+0x4f): undefined reference to `printf'
Ich nehme mal an, dass GCC nur keine Lust auf mich hat :D:(
Die drei zusätzlichen Fehler dürften davon kommen, dass du vergessen hast, die libc dazuzulinken. Mit -lc dürften zumindest diese drei wieder verschwinden (oder alternativ kannst du auch zum Linken wieder gcc aufrufen, der nimmt auch .o-Dateien und linkt die libc automatisch mit dazu).
-
main.o: file format pe-i386
Disassembly of section .text:
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
6: 83 e4 f0 and $0xfffffff0,%esp
9: b8 00 00 00 00 mov $0x0,%eax
e: 83 c0 0f add $0xf,%eax
11: 83 c0 0f add $0xf,%eax
14: c1 e8 04 shr $0x4,%eax
17: c1 e0 04 shl $0x4,%eax
1a: 89 45 f8 mov %eax,-0x8(%ebp)
1d: 8b 45 f8 mov -0x8(%ebp),%eax
20: e8 00 00 00 00 call 25 <_main+0x25>
25: e8 00 00 00 00 call 2a <_main+0x2a>
2a: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%ebp)
31: 8b 45 fc mov -0x4(%ebp),%eax
34: 89 04 24 mov %eax,(%esp)
37: e8 00 00 00 00 call 3c <_main+0x3c>
3c: 89 44 24 08 mov %eax,0x8(%esp)
40: 8b 45 fc mov -0x4(%ebp),%eax
43: 89 44 24 04 mov %eax,0x4(%esp)
47: c7 04 24 00 00 00 00 movl $0x0,(%esp)
4e: e8 00 00 00 00 call 53 <_main+0x53>
53: b8 00 00 00 00 mov $0x0,%eax
58: c9 leave
59: c3 ret
5a: 90 nop
5b: 90 nop
fact.o: file format pe-i386
Disassembly of section .text:
00000000 <factorial>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 08 mov 0x8(%ebp),%eax
6: 09 c0 or %eax,%eax
8: 75 07 jne 11 <recurse>
a: b8 01 00 00 00 mov $0x1,%eax
f: eb 10 jmp 21 <out>
00000011 <recurse>:
11: 48 dec %eax
12: 50 push %eax
13: e8 e8 ff ff ff call 0 <factorial>
18: 83 c4 04 add $0x4,%esp
1b: 8b 55 08 mov 0x8(%ebp),%edx
1e: 0f af c2 imul %edx,%eax
00000021 <out>:
21: 89 ec mov %ebp,%esp
23: 5d pop %ebp
24: c3 ret
25: 90 nop
26: 90 nop
27: 90 nop
-
Falls irgendwann irgendjemand das selbe Problem haben sollte ...
Der MinGW Compiler macht vor den externen funktionen automatisch ein _, wordurch er die Funktion im ASM-Code nicht mehr erkennt. Das kann man ganz einfach umgehen indem man in der extern deklaration im C-Code den _ vor die Funktion setzt und in der Assembler-Datei (im Falle des Tutorials "fact.S" auch. Danach sollte es wie im Beispiel erwähnt kompilieren gehen.
MfG
-
Also ist dein Problem glöst?
Programm Noob
-
yo, hab den guten service im irc channel noch zusätzlich in erwägung gezogen :). deshalb wollte ich hier eben mal die lösung posten.