Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: OsDevNewbie am 16. October 2014, 17:52
-
Hallo liebe community,
ich habe schon desöfteren gesehen, dass GCC beim kompilieren z.B. folgenden Codes
char *buffer = malloc(1, 1000);
In folgendes übersetzt:
char *buffer = malloc(1, 1000);
108a92: be e8 03 00 00 mov $0x3e8,%esi
108a97: bf 01 00 00 00 mov $0x1,%edi
108a9c: b8 00 00 00 00 mov $0x0,%eax
108aa1: e8 3f b6 ff ff callq 1040e5 <malloc>
108aa6: 48 63 d8 movslq %eax,%rbx
Oder manchmal setzt er auch anstatt movslq %eax,%rbx
das hier ein cltq
Wieso tut er das? Das ist ja fast fahrlässig, denn er zerstört damit eigentlich die oberen 64-bit der Adresse.
Ich kompiliere mit -m64 und der Host ist auch 64-bit.
Ich hoffe ihr könnt meine Frage beantworten.
-
Und wie ist deine malloc-Funktion deklariert?
-
So
void *malloc(size_t size)
So sollte es doch wohl gehen oder?
-
Die beiden malloc's passen nicht zusammen.
Einmal sind es 2 und einmal nur 1 Parameter.
Was für compiler flags nutzt du denn sonst noch so?
Irgend was in die Richtung "-mcmodel=small" ?
Es wäre auch interessant was danach so mit dem Pointer passiert. (rbx und rax)
-
Hallo,
oh ups, ich glaube da ist etwas noch falsch. Leider weiss ich nicht mehr die Stelle, von der ich diesen Code habe. Aber er macht es auch, wenn nur ein Parameter übergeben wird.
Das Flag "-mcmodel" habe ich nicht. Aber es könnte wohl daran liegen, denn laut Dokumentation von gcc wird standardmässig "-mcmodel=small" angenommen.
Nach dieser Instruktion behandelt er den Pointer wie ein richtiger Pointer also er nimmt immer die ganzen 64-bit.
Danke für die bisherigen Antworten.
-
Leider weiss ich nicht mehr die Stelle, von der ich diesen Code habe. Aber er macht es auch, wenn nur ein Parameter übergeben wird.
Das solltest du klären. C ist eine ziemlich simpel aufgebaute Sprache. Du solltest auf jeden Fall rauskriegen können, wie "malloc" deklariert ist. Ansonsten weg mit dem Code, den du dir da besorgt hast. Das klingt nicht gut, wenn du nicht weißt, wie der zu verwenden ist. Vor allem wenn der so einen Standardnamen wie "malloc" hat, ist das ein schlechtes Zeichen, wenn der nicht einfach so funktioniert. Vielleicht war der Code nie dafür gedacht wie du ihn verwendest.
Meine Theorie ist sonst, dass du den dazugehörigen Header nicht eingebunden hast, in dem diese Funktion deklariert ist, oder diese Funktion nicht korrekt deklariert ist.
Was genau sind deine Compilerflags?
-
Hallo zusammen,
ich habe jetzt herausgefunden woran es liegt. Ich habe vergessen die entsprechenden Headerdateien einzubinden.
Was für ein Flag benötige ich, dass mir gcc da wenigstens eine Warnung gibt?
Die Funktion malloc habe ich selber implementiert.
-
Ich vermute -Wall sollte reichen. Wenn du Errors statt Warnings haben willst, dann noch -Werror dazu. Und -pedantic nehm ich auch gerne noch. Siehe auch https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-
Also ich habe bei mir eigentlich -Wall und-pendantic eingschaltet. Aber vielleicht gibt er keine Warnungen aus, weil ich alle Unterordner mit -I einbinde.
In den Sourcedateien verwende ich nur die Direktive
#include "header.h"
Könnte es daran liegen?
-
Nein, das sollte so schon richtig sein.
-
Anscheinend nicht, denn bei mir kommen keine Warnungen. Er kompiliert es einfach so wie oben beschrieben.
-
Wie genau rufst du den Compiler auf? Woher kommt der Compiler (aus welcher Distribution? Oder selbstgebaut? etc.)? Für welches Target ist der Compiler? Mit welchen Flags kompilierst du? Damit könnte ich das Problem eventuell nachvollziehen.
-
Also der Compiler kommt aus der Distribution Linux Mint 17 (nicht selbstgebaut). Aktuelle Version ist 4.8.2. Aktuellster Stand (ja ich weiss es gibt jetzt schon 4.9.1 aber nicht in Mint). Ich benutze Eclipse als IDE dort habe ich alles eingegeben wie es sein muss. Wenn ich etwas anderes als meinen Kernel kompiliere (z.B. ein Programm für mein OS), dann gibt gcc Warnungen aus, wenn die Includedatei fehlt.
Der Compiler wird folgendermassen aufgerufen:
gcc -nostdinc -DBUILD_KERNEL -I"/home/pascal/Dokumente/YourOS/src/Kernel/cdi" -I"/home/pascal/Dokumente/YourOS/src/Kernel" -I"/home/pascal/Dokumente/YourOS/src/Kernel/driver" -I"/home/pascal/Dokumente/YourOS/src/Kernel/Include" -I"/home/pascal/Dokumente/YourOS/src/Kernel/lib" -I"/home/pascal/Dokumente/YourOS/src/Kernel/loader" -I"/home/pascal/Dokumente/YourOS/src/Kernel/mm" -I"/home/pascal/Dokumente/YourOS/src/Kernel/tasks" -I"/home/pascal/Dokumente/YourOS/src/Kernel/util" -O0 -Og -gdwarf-4 -pedantic -w -Wall -Wextra -c -fmessage-length=0 -m64 -ffreestanding -fno-stack-protector -mno-red-zone
(Das ist für den Debugmode. Für den Releasemode siehts ähnlich aus nur halt mit Optimierungen.)
Target ist folgender:
x86_64-linux-gnu
Ich hoffe das hilft dir ein bisschen.
-
Ich würde die ganzen -I"/pfad/zum/src/Kernel/xxx" zu einem -I"/pfad/zum/src/Kernel" zusammenfassen und dann die Headerdateien mit #include <xxx/header.h> einbinden. Alternativ könntest du statt Anführungszeichen auch spitze Klammern probieren. Allerdings bezweifle ich, dass das an deinem Problem etwas ändert.
Möglicherweise bessert sich was, wenn du -nostdinc weglässt und dich nur auf -ffreestanding verlässt...
-
Mit -w schaltest du alle Warnungen aus.
-w Inhibit all warning messages.
Du nutzt -O0 und -Og. Dabei wird -O0 ignoriert.
-Og [...]
If you use multiple ‘-O’ options, with or without level numbers, the last such
option is the one that is effective.
-
Mit -w schaltest du alle Warnungen aus.
-w Inhibit all warning messages.
Ah danke das war das Problem.