Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: nameac am 20. May 2006, 02:53

Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 02:53
mahlzeit,

habe c code mit asm code zusammen gelinkt indem ich in der *.asm

call  _main


aufrufe allerdings kommt dann kein "hello world" mhr wieso?
Titel: .c + .asm
Beitrag von: Coffee am 20. May 2006, 11:41
wie sieht denn deine main funktion in c aus??
Titel: .c + .asm
Beitrag von: Jidder am 20. May 2006, 11:41
Ich nehme mal eben Kontakt mit den Geistern unserer Vorfahren auf ... brb

*meditier* Ooooooooooooooooommmmmmmmmmmmm

re

Also sie haben mir geflüstert, dass etwas mit deinem Code oder deinem Compiler oder deinem Assembler oder deinem Linker oder deiner Testumgebung nicht stimmt. Sie sagen allerdings, dass es auch noch was anderes sein könnte.

Ich hoffe das hilft dir weiter.

(=> Mehr Details bitte!)
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 12:10
sorry ich dachte ihr wisst wo von ich spreche, hier noch mal genauer:

#include <stdio>

int main(){
printf('hello, welt\n');
return 0;
}


compeliert mit turbo c++ 1.0.1


EXTRN _MAIN:FAR

.MODEL SMALL

.STACK 256

.CODE
START: CALL  _MAIN
END   START


erzeuge *.obj datei mit masm

zum schluss tu ich noch beide *.obj dateien zusammen linken mit den nötigen libraries allerdings kommt dabei nur ein rücksprung zu dos programm raus, ich glaube der springt durch call _MAIN an die falsche stelle. bin mir nicht ganz sicher weil ich die *.obj dateien nicht vom debug.exe richtig disassembliert werden und an hand der zusammengelinkten exe kann man erkennen das der erste call nicht auf die gleiche stelle verweist die den anfang der mit turbo c++ erzeugeten exe bildet.
Titel: .c + .asm
Beitrag von: JensFZ am 20. May 2006, 12:14
Moin

Ähh du weist schon, dass du dir ne printf funktion selber schreiben musst.

MfG JensFZ
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 12:20
ne wisch nich wieso denn?
Titel: .c + .asm
Beitrag von: Coffee am 20. May 2006, 12:28
weil die printf nich von dir stammt^^ die "gehört" dem c - compiler
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 12:32
versteh ich nicht hab doch alle nötigen libraries beim linken angegeben der linker gibt auch keine fehler. die main wurde auch eingebunden aber halt nicht richtig meines achtens. weiß echt nicht was ihr gegen den aufruf einer bibliotheksfunktion habt.
Titel: .c + .asm
Beitrag von: Jidder am 20. May 2006, 12:35
Ich glaube, das ist nur ein DOS-Programm, oder?

Das ist nicht dein tatsächlicher Code. Das sieht man doch auf dem ersten Blick, dass der sich nicht kompilieren lässt.

#include <stdio.h> // <-- stdio gibt es nicht. nur stdio.h

int main(){
printf("hello, welt\n"); // <-- für strings immer doppelte anführungsstriche
return 0;
}
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 12:40
jetzt hab ich schon ne ausführliche beschreibung geliefert, aber bin ja geduldig, dies ist ein dos programm weil turbo c++ 1.0.1 der code ist absult korrekt und kann auch ausgefürt werden, aller dings nicht richtig wenn man ihn aus der assembler routine aufruft.
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 12:41
das mit .h war en schreib fehler
Titel: .c + .asm
Beitrag von: Jidder am 20. May 2006, 12:41
Nein ausführlich ist deine Beschreibung nicht. Und dein Code ist kein gültiges C. Siehe meine Korrekturen.

Wie rufst du zum Beispiel Assembler, Compiler und Linker auf?
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 12:49
in der eingabe aufforderung, tc.exe ist ein editor der nur in der eingbeaufderung startet und ist so komfortabel wie manch neue programme, damit compelier ich hello.c könnt ich auch mit dem reinen komandozeilen compiler >tcc hello.c
-d.h besitze hello.obj o0hne eingebundene libs und eine hello.exe mit eingebundene libs die auch über >hello.exe ausführbar ist

-ml /c h_prog.asm liefert mir ne h_prog.obj

-dann link h_prog.obj hello.obj und alle nötigen libs

-ergebnis h_prog.exe
Titel: .c + .asm
Beitrag von: Jidder am 20. May 2006, 13:19
Hm, okay. Also wie du vielleicht gemerkt hast, hast du dem Linker nicht mitgeteilt, dass dein Programm in der Assemblerdatei starten soll. Und ich hab auch keine Ahnung wie das geht. Deswegen mein Vorschlag: Nenn die Assembler-Funktion einfach _main.


asm.asm:
EXTRN   _CMAIN:NEAR ; das muss near sein, denn du hast dich für model small entschieden

.MODEL SMALL

.STACK   256

PUBLIC _MAIN ; damit der linker das _main symbol sieht

.CODE
_MAIN:
 CALL  _CMAIN ; zur c-routine springen
 RET ; das hast du vergessen ...
END   _MAIN


c.c:
#include <stdio.h>

int cmain() // von main() in cmain() umbenannt
{
    printf("hello, welt\n");
    return 0;
}


Assemblieren mit:
ml /c asm.asm

Kompilieren mit:
tcc -c c.c

Linken mit:
tlink c0s.obj asm.obj c.obj,test.exe,, cs.lib

Ich linke mit tlink, weil ich keine Lust habe, mich mit link auseinander zu setzen. Außerdem hab ich der Einfachheit halber c0s.obj und cs.lib aus dem LIB-Verzeichnis von TCC in das aktuelle Verzeichnis kopiert.

Du musst übrigens gegen c0s.obj linken, weil du gegen cs.lib linkst. Und du musst gegen cs.lib linken, weil du printf nutzt. Wenn du auf die Standardfunktionen verzichtest, kannst du auf diese beiden Dateien auch verzichten. Allerdings heisst der Einsprungspunkt dann anders. Wie weiss ich nicht, allerdings solltest du dann beim Linken eine Meldung mit dem Namen kriegen.
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 14:00
danke für deine hilfe, wußte garnicht das man in einer bestimmten reihenfolge linken muss. noch ne frage zum asm code warum sind im .model small nur near erlaubt vor mir liegt en buch wo auch far call im model small auftaucht auch der ret befehl ist für ein hauprogramm in diesem buch"assembler programmierung von wolfgang link" nicht beschrieben.
Titel: .c + .asm
Beitrag von: Jidder am 20. May 2006, 14:28
Keine Ahnung. Ich kenn mich mit MASM und TCC nicht aus, weil ich die nie benutzt habe. Ich würde sagen, das NEAR muss da hin, weil das .MODEL SMALL impliziert, dass der komplette Code innerhalb eines Segments ist. Ich weiss nicht ob, dann irgendwelche Informationen über das Segment von _CMAIN zur Verfügung stehen. Du kannst ja mal FAR ausprobieren.

Das RET hab ich dahin gemacht, weil ich das mal kurz disassembliert hatte, und kein RET gesehen hatte.

Normalerweise beendet man die Hauptroutine eines reinen Assemblerprogramms nicht mit RET (auch wenn es möglich ist) sondern mit Interrupt 21h, Funktion 4fh. Vermutlich steht es deswegen nicht in deinem Buch.

Hier wird allerdings ein RET benötigt, weil _MAIN nicht die tatsächliche Hauptroutine ist, sondern auch nur eine einfache Funktion, die von c0s.obj aufgerufen wird. Du kannst sie mit dem Interrupt 21h, Fkt 4fh beenden, wenn du willst, allerdings würde ich das nicht empfehlen, weil c0s.obj und cs.lib erwarten, dass du diese Funktion mit RET beendest.
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 14:43
mit welchen tools arbeitest du denn um so etwas zu realisieren eine buch empfehlung wär auch gut fals du eins kennst. em weißt du auch was man tun kann damit das programm bios int benutzt und keine dos int?
Titel: .c + .asm
Beitrag von: bluecode am 20. May 2006, 14:46
du musst dir deine eigenen Bibliotheken schreiben, welche dann nur BIOS ints benutzen. Als tools kann ich auf jeden Fall nasm/yasm empfehlen. Wenn du mal 32bit code hasst, dann auf jeden Fall gcc/g++.
Titel: .c + .asm
Beitrag von: Jidder am 20. May 2006, 14:50
Ich arbeite mit NASM, wenn es um Real Mode Code geht, und im Protected Mode zusätzlich noch mit der GCC. Bücher kann ich leider keine empfehlen, weil ich nie eins gelesen hab. Vielleicht kann ja jemand anders was dazu sagen.

Wenn du willst, dass das Programm nur BIOS Interrupts nutzt, musst du komplett auf die C-Library von Turbo C verzichten, weil die auf DOS aufsetzt. Das heisst du kannst keine vorgefertigten Header nutzen und musst dir sämtliche Funktionen wie printf selbst schreiben, wenn du sie nutzen willst.
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 15:04
ich hatte mir das so vorgestellt, habe das tutorial über bootloader gelesen und mal in masm übersetzt und ein wenig damit rum gespielt, aller dings kann ich mir nur schwer vorstellen ein größeres progamm das vom bootloader geladen werden soll nur in assembler zu schreiben deshalb hab ich nach einer möglichkeit gesucht c_functionen aus asm_functionen aufzurufen und dachte das man dann auch die riesigen bibliotheken nutzen kann um etwas größere progamme schnell schreiben zu können.
Titel: .c + .asm
Beitrag von: Coffee am 20. May 2006, 17:31
ne. das darfste ja net^^
Titel: .c + .asm
Beitrag von: nameac am 20. May 2006, 22:52
dann bräuchte ich noch mal ne erklährung über interrupts z.B. wie sind die dos int's implementiert das sind doch selbst geschriebene funktionen?

hab schon mal gegoogelt aber wie das so ist findet man anfangs nur schwer infos über themen zufinden von den man selbst noch wenig ahnung hat und man garnicht genau weiß wonach man suchen muss.

bisher weiß ich nur das man die bios ints z.B.zum laden von daten, eines mediums wie z.B diskette oder festplatte, in den RAM braucht und diese sind fest auf einen eprom oder eeprom implementiert, also wie kommen die dos ints in den rechner, kann man eigene routinen programmieren die daten von z.B. diskette laden ohne die bios ints zu benutzen?
Titel: .c + .asm
Beitrag von: bluecode am 20. May 2006, 23:08
Zitat von: nameac
bisher weiß ich nur das man die bios ints z.B.zum laden von daten, eines mediums wie z.B diskette oder festplatte, in den RAM braucht und diese sind fest auf einen eprom oder eeprom implementiert

Jo, die BIOS ints sind in nem ROM, aber man kann mit ihnen nur Sektoren einer Festplatte/Diskette lesen, nicht direkt Dateien, da das BIOS noch keine Dateisysteme unterstützt.

Zitat von: nameac
also wie kommen die dos ints in den rechner

Wenn du DOS installiert hast, dann wird das nach dem BIOS gestartet. DOS initialisiert dann die DOS spezifischen Interrupts.

Zitat von: nameac
kann man eigene routinen programmieren die daten von z.B. diskette laden ohne die bios ints zu benutzen?

Ja, kann man. Eigene Interrupts muss man in die IVT (=Interrupt Vector Table) eintragen, dann kann man auch die über "int xx" aufrufen. Wenn du direkt auf Hardware zugreifen willst, dann musst du dir erstmal die entsprechenden Standards (für IDE Festplatten zB ATA/ATAPI) durchlesen und danach halt wie dort beschrieben auf die Hardware zugreifen. Dies geschieht normal über I/O Ports (Befehle in/out/ins/outs) oder über in den Speicher gemappte "Ports" (die man ganz normal über mov ansprechen kann).