Anfänger Frage



  • und auch bei borland kannst du das unter compiler-optionen schön aktivieren (generate assembler-output) wenn du das machst, um assembler besser zu verstehen, würde ich dir außerdem noch empfehlen, die ganzen sachen mit optimierung zu deaktivieren, das kann sonst u.U. recht schwer nachvollziehbar sein, auch wenn alle paar zeilen der equivalente C/C++ code steht (zumindest bei borland, bei gcc hab ichs noch nicht probiert)



  • Danke erstmal für die Antworten.

    Vielleicht könnt ihr mir nochmal helfen. Ich hab schon im FAQ aber nicht so viel gefunden.

    Ich bräuchte mal ein paar Beispiele für folgende Sachen, dann denke ich komme ich ganz gut alleine klar.

    1. Eine normale eingabe. Z.B. zwei zahlen um mit ihnen zu arbeiten, addieren usw.
    2. Parameterübergabe für Zeiger und Arrays mit INVOKE.
    3. Wie man unter Assembler eine Datei öffnet und den Inhalt in ein Array speichert. In der Textdatei sind alles Zahlen.

    Das alles zugeschnitten auf INT 21h, mit MASM und keine Mischsprache mit C oder anderen Hochsprachen.

    MfG
    Oliver



  • Willst du jetzt Windows-Programme in Assembler schreiben oder nur kleinere Routinen in Objekte auslagern und diese in C verwenden (oder gar nur Inline-Assembler)?
    Für's erste findest du auf meiner Seite ein paar Tutorials (www.joachimrohde.de, steht aber auch in der FAQ). Ansonsten schau dir die ersten zwei Tutorials dort an, dann solltest du wenigstens wissen, was es mit INVOKE auf sich hat.



  • Ne keine Windows Programme.
    Nur 16-Bit Assembler für DOS.

    MfG
    Oliver



  • Kann mir keiner ein paar Beispiele geben?

    Was ich dringen brauche ist zur Zeit die eingabe von zwei Zahlen, ich finde überall nur string eingaben und das auch nicht gerade perfekt.

    MfG
    Oliver



  • Hi.

    Zahlen einlesen unter DOS gibt es nicht fertig.

    Grundsaetzlich sollte es beim Umwandeln eines Strings mit dec. Zahlen ja so ablaufen, dass die Ziffern der eingegebenen Zahl einzeln aus dem String ausgelesen (beginnend mit der hoechsten 10er-Potenz versteht sich - aber die ist in einem String meist eh vorn 😉 ) und zu einer Variable addiert werden, die zudem bei jedem Schleifendurchlauf sinnvollerweise vor og. Addition mit 10 mutlipliziert wird.

    Der code koennte dann zB. so aussehen:

    mov si,offset MyString ;Abbruchbedingung ist ein Zeichen, dass keine Ziffer
    ;(0-9) ist.
    mov ax,0000h
    mov di,000Ah
    @@Loop:
    movzx bx,[byte ptr ds:si]
    sub bl,30h ;ASCII-Code von "0" abziehen
    jc  short @@Exit ;bei gesetztem CF gab es einen overflow beim addieren,
    ;folglich war bl<30h und somit keine Ziffer von 0-9.
    cmp bl,09h
    ja  short @@Exit
    inc si    ;naechstes Zeichen
    mul di    ;*10
    add ax,bx ;+Ziffer
    jmp @@Loop
    @@Exit:
    

    [edit]Code berichtigt[/edit]



  • Ok danke nochmal für all die Antworten, habt mir schon einiges geholfen.
    Aber ich habe noch eine Frage.

    kann mir einer vielleicht mal helfen folgenden code ein bisschen besser zu verstehen? ich hab scho so weit kommentiert wie ich das weiß, aber vielleicht kann mir da noch jemand helfen.
    Hatte den Code im Internet gefunden

    input PROC var:WORD,lenght:WORD             
            mov ah,03fh   ;Interrupt zum einlesen
            xor bx,bx     ;bx auf 0 setzten stdin
            mov cx,lenght ;die maximallänge setzen, im programm oben festgelegt
            mov dx,var    
            int 21h       ;DOS-Interrupt
            ;so hab hier versteh ich nicht warum das gemacht wurden ist
            sub ax,2 
            mov bx,var 
            add bx,ax 
            mov byte ptr [bx],0
            ret 
    input ENDP 
    
    ;hier das versteh ich irgendwie nicht so richtig
    strlen PROC string:WORD 
            mov si,string 
            @@: 
            mov al,byte ptr [si] 
            inc si 
            or al,al 
            jnz @b 
            dec si 
            sub si,string 
            xchg ax,si 
            ret 
    strlen ENDP
    

    Hoffe mir kann dabei jemand helfen.

    MfG
    Oliver



  • @Nubuo T : Tut mir leid, dass ich hier dieses alte Topic wieder vorkrame, aber ich hab' da ein Problem mit deinem Beispiel...Du schreibst u.a.

    @@Loop:
    movzx bx,[byte ptr ds:si]
    add bl,-30h ;ASCII-Code von "0" abziehen
    

    Bei mir kann der Assembler (MASM) nix mit der Zeile movzx bx,[byte ptr ds:si] anfangen und gibt mir folgende Fehlermeldung:

    Assembling...
    calc.asm(88) : error A2085: instruction or register not accepted in current CPU mode

    Make error(s) occured.

    Ich habe hier einen XP-Rechner mit Pentium4. Könntest du mir erklären, wo da bei mir das Problem ist bzw. wie man es umgehen kann ?
    Dankeschön schoma im vorraus & noch einen schönen Abend
    Gruß
    E-the-Real



  • Tja, kann es sein, dass du lediglich Code fuer 286/87-CPU erzeugen laesst?
    Die kennen weder 32Bit-Register, noch die movzx-Instruktion.
    Irgendwo am Anfang deines Programms sollte eine Zeile, wie ".286" oder so stehen. Wenn nicht, fuege einfach ein ".586" ein, dann bist du mit Code fuer Pentium auf der sicheren Seite.



  • hmm, da kommt dann ein neuer Fehler...der alte is zwar weg, aber ich erhalte nun

    calc.asm(80) : error A2032: invalid use of register

    Make error(s) occured.

    Am besten ich poste mal den Code...

    .586
    PUFFER SEGMENT
    	tmpstr db 05h,00h	;5 zahlen maximal einlesen 
    	db 05h dup(?) 		;Speicher reservieren
    PUFFER ENDS
    
    CODE SEGMENT
    
    start:
    var dw ?
    mov ax,PUFFER   
    mov ds,ax 
    lea dx,tmpstr
    mov ah,0Ah	;String einlesen
    int 21h
    
    ;;;;;;;;;;;;;;Hier dein Code;;;;;;;;;;;;
    
    	push ax
    	push bx
    	lea si,tmpstr
    	mov ax,0
    	mov di,10
    separate:
    	movzx bx,[byte ptr ds:si]  ;FEHLER s.o.
    	add bl,-30h
    	jc short exit1
    	cmp bl,09h
    	ja exit1
    	inc si
    	mul di
    	add ax,bx
    	jmp separate
    exit1:
    	mov var,ax
    	pop bx
    	pop ax
    
             mov ah,4ch
             int 21h
    	CODE ENDS
    END start
    

    Wär schön, wenn du mir da weiterhelfen könntest...
    Gruß
    E-the-Real



  • Moin, Moin...

    Ändere

    movzx bx,[byte ptr ds:si]  ;FEHLER s.o.
    

    in

    movzx bx,[byte ptr si]
    

    Du musst das Register DS nicht explizit angeben. DS wird standardmäßig bei den mov-Befehlen benutzt. Wenn Du aber dennoch ein anderes Segmentregister benutzen möchtest, lautet der Befehl:

    movzx bx, ds:[byte ptr si]
    

    Ciao...



  • hmm, da kommt immer noch die gleiche Fehlermeldnung...langsam verzweifel ich hier 😞



  • Ok, dann versuch halt mal das:

    movzx bx, byte ptr [si]
    

    MASM is halt ein bissel komisch. :p



  • Ahhh, tausend Dank, es funzt ! 🙂
    Gruß
    E-the-Real



  • Also, erst mal dankeschön für eure Mühen, aber ich muß euch noch weiternerven:
    Erstmal zu deinem letzten Post: Wenn ich das Programm nun assembliere, kommen diesbezüglich keine Fehlermeldungen mehr, allerdings gibt es noch eine andere... 😡 Ich poste hier noch einmal das ganze Programm:

    .586
    
    daten segment 
    	TempStr db "125","$"
    daten ends
    
    code segment
    assume ds:daten,cs:code 
    start:
    mov ax,daten
    mov ds,ax
    ;Hier der Nubuo T - Algorithmus 
    mov si,offset TempStr	; Fehler 1 
    mov ax,0000h 			
    mov di,000Ah 			
    @@Loop: 
    movzx bx,byte ptr [si] 	
    add bl,-30h					
    jc short @@Exit 			
    cmp bl,09h 					
    ja short @@Exit 			
    inc si  					
    mul di 						
    add ax,bx  					 
    jmp @@Loop 					
    @@Exit: 
    ;deciout:Ausgabe einer Dezimalzahl
    call deciout
    
    ;Beenden
    mov ah,4ch
    int 21h
    
    deciout proc near
    	push ax
    	push bx
    	push cx
    	push dx
    	mov bx,10
    	mov cx,0
    	division:
    	inc cx
    	mov dx,0
    	div bx
    	push dx
    	cmp ax,0
    	jne division
    	mov ah,2
    	output:
    	pop dx
    	add dl,30h
    	int 21h
    	loop output
    	pop dx
    	pop	cx
    	pop bx
    	pop ax
    
    	ret
    
    deciout endp
    code ends
    end start
    

    Eure Hinweise waren schonmal sehr hilfreich, auch das .586 klappt. Allerdings verwundert mich eine Sache: Die markierte Zeile

    mov si,offset TempStr	; Fehler 1
    

    liefert den Fehler

    Assembling...
    strint.asm(13) : error A2022: instruction operands must be the same size

    Make error(s) occured.

    ,wohingegen folgendes funktioniert:

    lea si,TempStr
    

    Das verstehe ich nicht, da doch IMHO beides identisch ist, oder irre ich mich da ???
    Weiterhin sollte das Programm die Zahl im String TempStr ausgeben. Jetzt sagt mir bitte nicht, dass dies ein umständlicher Weg ist, den String erst in eine Zahl umzuwandeln und diese dann wieder in einen String; das ist mir klar, aber ich habe diese beiden Funktionen einfach mal nebeneinander gestellt, um zu prüfen, ob sie funzen. Mein Ziel ist es, einen einfachen Taschenrechner zu proggen (macht euch bitte nicht lustig - jeder fängt mal klein an ;), bei dem man zwei Zahlen eingibt (die mehr als eine Ziffer haben können) und dann ein kleines Menü à la

    Addieren       1
           Subtrahieren   2
           Dividieren     3
           Multipl.       4
           Bitte Option eingeben....
    

    kommt.
    Dabei scheiter ich momentan allerdings kläglich und bin schon ganz verzweifelt. Also, bitte helft mir da ein wenig auf die Sprünge. Ich hab zwar schon zig Tuts gezogen, aber irgendwie meiden die alle die Ein- & Ausgabe von Zahlen...
    Nochmals vielen Dank für eure Mühen
    Gruß
    E-the-Real



  • Der Fehler liegt da, dass du das .586 ueber das Datensegment gesetzt hast.
    Nun nimmt MASM erstmal an, dass es sich hierbei um ein 32Bit-Segment handelt.
    Also entweder du gibst ganz oben eine 16Bit-CPU an (zB. .8086) und im Codesegment erst den 586 oder du gibst beim Datensegment explizit an, dass 16Bit benutzt werden sollen (hinter "segment" "USE16" schreiben).
    Das koenntest du dann auch noch beim Codesegment machen.

    [edit]PS:
    Wenn das Forum mal wieder haengt, bitte nicht tausend mal auf "absenden" klicken.
    Wie du vielleicht gemerkt hast, kommt das Posting in den meisten Faellen noch an. ;)[/edit]



  • Sorry, das wusst ich net, denn normalerweise funzt bei mir das Forum, ich dachte, das läge an meinem Provider, da der öfters etwas spinnt...
    Also, nochmal dankeschön, aber ich hab's jetzt mal so probiert:

    mov si,offset Instring
    xor ax,ax
    mov di,000Ah
    @Loop:
    xor bh,bh
    mov bl,[si]
    add bl,-30h
    jc @Exit
    cmp bl,09h
    ja @Exit
    inc si
    mul di
    add ax,bx
    jmp @Loop
    @Exit:
    

    Im Wesentlichen ist das ja identisch mit deiner Version, ich habe lediglich movzx bx,byte ptr [si] durch xor bh,bh und mov bl,[si] ersetzt. Damit komme ich dann ganz ohne .586 aus. Trotzdem funktioniert der "Algorithmus" nicht richtig, da immer eine 0 ausgegeben wird. Instring ist die Adresse von einem String, den ich davor einlese und der mit einem $ abgeschlossen wird. Da kann der Fehler allerdings nicht liegen, da ich den String mit

    mov dx, offset Instring
    mov ah,9h
    int 21h
    

    ausgeben kann...Der Fehler muß also irgendwo da oben stecken, das kann doch nicht am masm liegen, oder ? Dann noch eine Frage: Die Sprunganweisungen haben bei dir noch ein short davor, also "ja short @Exit". Wozu ?
    Viele Grüße
    E-the-Real



  • ethereal schrieb:

    Trotzdem funktioniert der "Algorithmus" nicht richtig, da immer eine 0 ausgegeben wird.

    Jo, sehs gerade 🙄 :
    Wird vermutlich hier dran liegen=>
    "add bl, -30h"
    Hierbei wird sinnigerweise immer das cf gesetzt, was sofort zum Exit fuehrt.
    Mach daraus "sub bl, 30h", dann sollte das funktionieren.

    ethereal schrieb:

    Dann noch eine Frage: Die Sprunganweisungen haben bei dir noch ein short davor, also "ja short @Exit". Wozu ?

    Im IDEAL-Mode von TASM wird bei 386+Code normalerweise beim Assemblieren Platz fuer ein long jump im Code reserviert. Sollte sich das ganze dann doch mit einem short jump loesen lassen, bleiben die Platzhalter (nops) hinter den jumps stehen.
    Sehr nervig => das Schluesselwort "short" erzwingt die Verwendung von short jumps.
    Keine Ahnung, wie das bei MASM ist.



  • JUCHU !!!! Tausend Dank, es funktionier ! 😋
    Also, hier noch mal für alle der richtige Algo.:

    ;Hier der Nubuo T - Algorithmus 
    mov si,offset TempStr     
    mov ax,0000h             
    mov di,000Ah             
    @@Loop: 
    xor bh,bh
    mov bl,byte ptr [si]     
    sub bl,30h                    
    jc short @@Exit             
    cmp bl,09h                     
    ja short @@Exit             
    inc si                      
    mul di                         
    add ax,bx                        
    jmp @@Loop                     
    @@Exit:
    

    Nochmal Dankeschön !
    Viele Grüße
    E-the-Real


Anmelden zum Antworten