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 gefundeninput 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 modeMake 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 sizeMake 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ü à laAddieren 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