in assembler geschriebene programme im terminal aufrufen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • in assembler geschriebene programme im terminal aufrufen

    Hi!


    erstmal hallo! ich bin seit kurzem im forum angemeldet.

    ich studiere an der FH Frankfurt Informatik und hab mir zu studienbeginn einen mac besorgt.

    derzeit schreiben wir einiges in assembler, aber ich hab das problem, daß meine in assembler geschriebenen programme im terminal nicht ausgeführt werden. linken und assemblieren geht wunderbar, nachdem einige besonderheiten erücksichtigt wurden (z.B. .globl statt .global oder das man das symbol _start nicht nutzen kann. zumindest hat der as gemosert.)


    wie kann ich meine in assembler geschriebenen programme im terminal aufrufen, um deren funktion zu prüfen? muß ich da bestimmte parameter setzen? oder sind da bestimmte datei endungen zu beachten?

    als beispiel sei folgendes programm:

    start:
    .globl start

    movl $3,%eax #systemaufruf read = eingabe
    movl $0,%ebx #stdin
    movl $ZK,%ecx #adresse Zeichenkette ZK
    movl $80,%edx #80 zeichen können maximal gespeichert werden.
    int $0x80 #interrupt
    movl %eax,L_ZK #länge der eingabe als rückgabewert(?)

    movl $4,%eax #systemaufruf write = ausgabe
    movl $1,%ebx #stdout
    movl $ZK,%ecx #Adresse der Zeichenkette ZK
    movl L_ZK,%edx #länge der Zeichenkette
    int $0x80 #interrupt

    movl $1,%eax #programmende
    movl $0,%ebx #
    int $0x80 #

    .data
    ZK: .space 80
    L_ZK: .long 0


    es soll eine eingabe und eine ausgabe stattfinden.

    danke im voraus für weiterführende hinweise.

    die referenz zu assembler hab ich als pdf-file aber die half mir nicht weiter.

    greez

    Naph
  • da steht aber leider nix zum aufruf des geschriebenen codes. ich kann den code assemblieren und linken. wenn ich aber die ausführbare datei aufrufe passiert nix.

    ich habe die datei als .x als .out und sogar als a.out erstellt. aber wenn ich das programm starte, dann komm ich nur wieder zur kommandozeile zurück ohne das etwas passiert ist.
  • aber main ist doch nichts anderes als ein symbol. und wenn ich das richtig verstanden hab ist es doch egal wie das symbol genannt wird.

    oder wie ist main zu verstehen?

    ich hab das programm mit verschiedenen versuchen gestartet und die oben stehende version hat sich ohne probleme assemblieren und linken lassen.

    vielleicht kann ja einer mal eins seiner beispielprogramme posten, damit ich mal vergleichen kann...bisher schreibe ich die programme auf nem linux rechner in der FH aber ich will auf längere sicht gesehen den kram auch auf dem mac ausführen können.

    danke


    Naph
  • hmm...also wenn ich das mit main mache kommt diese fehlermeldung:

    localhost:~ <user>$ as -o successor.o successor.s
    localhost:~ <user>$ ld -o successor.out successor.o
    ld: could not find entry point "start" (perhaps missing crt1.o) for inferred architecture i386


    dabei ist es egal ob mit main oder mit _main
  • _main natürlich meinte ich.

    Hmm dann scheint der Launcher in der Tat start zu suchen. Mea culpa! Muss ich mir morgen wohl noch einmal genauer anschauen. Für heute Abend war es zu viel Bier.

    Gerade fällt mir noch auf, dass du kein .text-Segment definiert hast. Macht dein Assembler das defaultmäßig?
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • keine ahnung...ich hab den standardmäßigen MachO gnu based assembler drauf, falls dir das was sagt. ich hab den apfel aber auch erst sein etwas über 3 wochen...also noch nich so den plan vom inhalt...ich kämpf mich halt durch's system...mit mehr oder weniger erfolg...
  • ich hab eins meiner früheren programme auf die art compiliert...dabei entstand dann folgender code:

    .cstring
    LC0:
    .ascii "woozaaa\0"
    LC1:
    .ascii "G.I.Joe\0"
    .text
    .globl _main
    _main:
    pushl %ebp
    movl %esp, %ebp
    pushl %ebx
    subl $36, %esp
    call L9
    "L00000000001$pb":
    L9:
    popl %ebx
    movl $0, -12(%ebp)
    jmp L2
    L3:
    leal LC0-"L00000000001$pb"(%ebx), %eax
    movl %eax, (%esp)
    call L_puts$stub
    leal -12(%ebp), %eax
    incl (%eax)
    L2:
    cmpl $4, -12(%ebp)
    jle L3
    movl -12(%ebp), %edx
    movl %edx, %eax
    shrl $31, %eax
    addl %edx, %eax
    sarl %eax
    movl %eax, -12(%ebp)
    cmpl $0, -12(%ebp)
    je L8
    leal LC1-"L00000000001$pb"(%ebx), %eax
    movl %eax, (%esp)
    call L_printf$stub
    L8:
    addl $36, %esp
    popl %ebx
    leave
    ret
    .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
    L_printf$stub:
    .indirect_symbol _printf
    hlt ; hlt ; hlt ; hlt ; hlt
    L_puts$stub:
    .indirect_symbol _puts
    hlt ; hlt ; hlt ; hlt ; hlt
    .subsections_via_symbols
  • ich buddel das mal aus...weil irgendwie klappt das immer noch nich...

    (ich hab zwischenzeitlich auf linux geschrieben...daher hatte ich keine zeit mich damit weiter zu befassen...)


    ich hab folgenden code von meinem prof erhalten...

    .data

    ######## KOMMENTARE

    K1: .ascii "Bitte eine Zeichenkette eingeben: "
    L_K1: .long .-K1
    K2: .ascii "Sie haben eingegeben: "
    L_K2: .long .-K2
    K3: .ascii "Die neue Zeichenkette lautet: "
    L_K3: .long .-K3
    K4: .ascii "Anzahl der U: "
    L_K4: .long .-K4

    ######## PLATZ FÜR ZEICHENKETTEN

    ZK: .space 80
    L_ZK: .long 0
    ZK_NEU: .space 80

    ######## SONSTIGE WERTE

    ANZAHL_U: .long 0
    NL: .byte 10

    ######## MAKROS FÜR EIN- UND AUSGABE

    .macro OUT ADR LEN
    movl $4, %eax
    movl $1, %ebx
    movl \ADR, %ecx
    movl \LEN, %edx
    int $0x80
    .endm

    .macro IN ADR MAXLEN ACTLEN
    movl $3, %eax
    movl $0, %ebx
    movl \ADR, %ecx
    movl \MAXLEN, %edx
    int $0x80
    movl %eax, \ACTLEN
    .endmacro

    .macro NEWLINE
    OUT $NL $1
    .endmacro

    ###########################################################################

    .text

    .globl _start

    ###########################################################################
    # Prozedur WRITE_UNSIGN_LONG_DEC
    #
    ###########################################################################

    write_unsign_long_dec:
    pushl %ebp # ebp retten
    movl %esp,%ebp # esp --> ebp
    subl $12,%esp # Platz fuer Zeichenkette
    pushal # Regs. retten
    movl 8(%ebp),%eax # Eingabewert vom Stack holen
    movl $10,%esi # Divisor
    movl %ebp,%ecx # Reg. fuer indirekte Adressierung
    NON_ZERO:
    decl %ecx # ecx -1 --> ecx
    movl $0,%edx # fuer Division
    divl %esi # eax / 10
    addb $'0,%dl # Rest --> ASCII-Ziffer
    movb %dl,(%ecx) # Ziffer abspeichern
    cmpl $0,%eax # Quotient = 0?
    jne NON_ZERO
    movl $4,%eax # Syscall write vorbereiten
    movl $1,%ebx # stdout
    movl %ebp,%edx # Laenge berechnen
    subl %ecx,%edx
    int $0x80 # Syscall
    popal # Regs. wiederherstellen
    movl %ebp,%esp # lokaler Speicher freigeben
    popl %ebp # ebp wiederherstellen
    ret

    ###########################################################################
    # Prozedur X2U, um x durch u zu ersetzen
    ###########################################################################

    X2U:
    # ebp und esp sichern, ebp als Basis-Adresse verwenden
    pushl %ebp
    movl %esp, %ebp

    # verwendete Register sichern
    pushl %ecx
    pushl %edx
    pushl %esi
    pushl %edi

    # Parameter abholen
    movl 8(%ebp), %ecx # L_ZK
    movl 12(%ebp), %edi # ZK_NEU
    movl 16(%ebp), %esi # ZK

    # eigentliche Funktion

    movl $0, %eax # Anzahl der U, zu Beginn 0

    L:
    movb (%esi), %dl # Zeichen lesen

    cmpb $'x, %dl # ist das Zeichen ein x?
    jne KEIN_X # falls nicht, springen

    movb $'u, %dl # x durch u ersetzen

    KEIN_X:

    cmpb $'u, %dl # ist das Zeichen ein u?
    jne KEIN_U # falls nicht, springen

    incl %eax # bei u hochzählen

    KEIN_U:

    movb %dl, (%edi) # Zeichen kopieren

    # Quell- und Zieladresse um 1 erhöhen
    incl %esi
    incl %edi

    loop L

    # gesicherte Register wiederherstellen
    popl %edi
    popl %esi
    popl %edx
    popl %ecx

    # esp und ebp wiederherstellen
    movl %ebp, %esp
    popl %ebp

    # zurück zum Hauptprogramm
    ret

    ###########################################################################
    # HAUPTPROGRAMM
    ###########################################################################

    _start:
    # Ausgabe Kommentar 1
    OUT $K1 L_K1

    # Einlesen der Zeichenkette und Abschneiden des \n
    IN $ZK $80 L_ZK
    decl L_ZK

    # Ausgabe Kommentar 2 und Kontrollausgabe der ZK
    OUT $K2 L_K2
    OUT $ZK L_ZK
    NEWLINE
    NEWLINE

    # Falls ZK leer ist, direkt zum Ende springen
    cmpl $0, L_ZK
    je KEINE_ZK

    # Unterprogramm-Aufruf vorbereiten
    pushl $ZK
    pushl $ZK_NEU
    pushl L_ZK

    # Unterprogramm aufrufen
    call X2U

    # Stack bereinigen
    addl $12, %esp

    # Anzahl der U in Speicher schreiben
    movl %eax, ANZAHL_U

    KEINE_ZK:

    # Ausgabe Kommentar 3 und neue ZK
    OUT $K3 L_K3
    OUT $ZK_NEU L_ZK
    NEWLINE

    # Ausgabe Kommentar 4
    OUT $K4 L_K4

    # Ausgabe der U-Anzahl über Unterprogramm

    pushl ANZAHL_U
    call write_unsign_long_dec
    addl $4, %esp

    NEWLINE

    # Programm beenden
    movl $1, %eax
    movl $0, %ebx
    int $0x80



    und jedesmal erhalte ich beim assemblieren folgende fehlermeldung:

    test3.s:153:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:156:junk `$80L_ZK' after expression
    test3.s:156:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:160:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:161:junk `L_ZK' after expression
    test3.s:161:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:162:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:163:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:186:junk `L_K3' after expression
    test3.s:186:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:187:junk `L_ZK' after expression
    test3.s:187:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:188:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:191:junk `L_K4' after expression
    test3.s:191:no instruction mnemonic suffix given and no register operands; can't size instruction
    test3.s:199:no instruction mnemonic suffix given and no register operands; can't size instruction


    aber auch wenn ich einen as-code per gcc -S erstelle kommt beim linken dann die meldung

    ld: could not find entry point "start" (perhaps missing crt1.o) for inferred architecture i386


    das programm soll in einer zeichenkette alle x finden und durch u ersetzen. und alle u's zählen. das ganze mit einem unterprogramm und einem eingabe und einem ausgabe macro....

    und ich hab keinen schimmer wieso das nicht läuft...

    kann mir einer sagen wo ich den fehler übersehe? ich krieg nämlich grad tierische kopfschmerzen....
  • Also man muss ein Runtime-Library dazulinken, meist crt.o (wie es auf dem Mac genau heißt weiss ich nicht auswendig). Die wird durch 'start' angesprungen, macht dann alle Initialisierungen bevor sie dann selbst main() aufruft.

    Wenn man mit gcc -o a.out files.S übersetzt müsste sie aber standardmäßig dazugelinkt werden.

    Wenn man mit -c übersetzt, dann wird gar nicht gelinkt.

    Und wenn man ld von Hand aufruft wird auch keine Runtime automatisch dazugelinkt.

    Ach ja:
    localhost:~ <user>$ as -o successor.o successor.s
    localhost:~ <user>$ ld -o successor.out successor.o
    ld: could not find entry point "start" (perhaps missing crt1.o) for inferred architecture i386
    Er sagt doch eindeutig was fehlt: crt1.o

    => ld -o successor.out successor.o /Pfad.../crt1.o

    -- hns
  • aha.....ok...das strange an der sache is jetzt, daß ich trotz fehlermeldung eine ausführbare datei erzeugt bekomme (hab mit einem testcode schlicht main(){} mit gcc -S eine .s-file erstellt, deswegen die frage nach dem missing-crt1.o-errortext) :sick: ...und die crt1.o ist auch vorhanden. ..zumindest laut spotlight...



    das löst nur ein teil des problems...denn die fehlermeldungen beim assemblieren bleiben bestehen...ergo kann ich die datei nicht linken...



    edit:


    wo kann ich eigentlich die fehlermeldungen nachschlagen? ich hab die ADC und die man pages schon durchforstet...hab nix gescheites gefunden....und der mac os x assembler guide liefert auch nix...
  • Original von naphaneal
    Wo kann ich eigentlich die fehlermeldungen nachschlagen? ich hab die ADC und die man pages schon durchforstet...hab nix gescheites gefunden....und der mac os x assembler guide liefert auch nix...
    Eine ein bischen gemeine Antwort: im Englisch-Deutsch-Wörterbuch...

    test3.s:153:no instruction mnemonic suffix given and no register operands; can't size instruction

    sagt: der erste Fehler ist in Zeile 153 => im Source suchen.
    es fehlt ein Suffix (.b .w. l oder sowas in der Art)
    und keine Register angegeben.
    Daher weiss der Assember nicht welche Operandenbreite er einbauen soll.

    Also ist der Assemblerbefehl falsch. Den schaut man in einem geeigeten Microprocessor Programming Guide nach.

    (Ich bleibe deshalb ein bischen allgemein, weil ich mich das letzte Mal vor ca. 20 Jahren mit der amaligen i86-Architektur auseinandergesetzt habe. M680x0 oder ARM könnte ich Dir konkret sagen was los ist).

    Ins Blaue: es scheint etwas mit den Makrodefinitionen und Aufrufen zu tun zu haben. Muss man da vielleciht Kommas nehmen um die Argumente zu trennen?

    Ich vermutet das wegen der Meldung test3.s:156:junk `$80L_ZK' after expression wo es aber im Source "IN $80 L_ZK" heißt. Also bis zur Fehlermeldung wird das Leerzeichen entfernt...

    -- hns
  • man nimmt kommas um die register bei zuweisungen zu trennen also z.B.

    %eax,%ebx

    das mit dem byte long und word is mir noch gar nich gekommen...werd das mal überprüfen...danke...

    und was ich mit nachschlagen meinte is...wo steht mal eine erklärung zu dem fehler...weil die fehlermeldung sagt mir gar nix...
  • Original von naphaneal
    nachschlagen meinte is...wo steht mal eine erklärung zu dem fehler...weil die fehlermeldung sagt mir gar nix...
    Ich glaube die unterstellen einfach dass wer heute noch Assembler programmiert sehr viele Dinge einfach weiß bzw. das Fachvokabular beherrscht... Deshalb gibt auch keine ausführlicheren Beschreibungen.

    Wenn Du die Begriffe:
    Mnemonic
    Suffix
    to size an instruction

    genau kennst dann braucht es keine weitere Erklärung.

    -- hns