Zeichen aus Zeichenkette auslesen
-
Hallo!
Ich möchte aus einer Zeichenkette ein einzelnes Zeichen auslesen siehe Beispiel. Ich programmiere dies mit dem NASM und unter Linux. Mit
mov ecx, msg + 4
kann ich das o auslesen/anzeigen. Ich möchte die 4 aber durch eine Variable ersetzen zum Beispiel aus einem Register oder Speicherwert. Ich bekomme das aber nicht hin. Kann mir einer einen Tipp geben wie ich das realisieren kann?
Danke schon mal!
Hier ein Beispieltext:
section .data msg db "Hallo Welt!", 0xa len equ $ - msg section .text global _start _start: ;Textausgabe mov eax, 4 mov ebx, 1 mov ecx, msg mov edx, len int 0x80 ;ein Zeichen aus Zeichenkette mov eax, 4 mov ebx, 1 mov ecx, msg + 4 ;o wird ausgegeben mov edx, 1 int 0x80 mov eax, 1 mov ebx, 0 int 0x80
-
Kopiere deine Variable (Offset innerhalb des Strings - zB. 4) nach ecx und addiere dann das Offset des Strings drauf (oder umgekehrt). Sollte klappen.
Also in etwa:
mov ecx, msg add ecx, ... (whatever, zB. 4)
-
Danke nochmals, es funktioniert.
Nun wieder ein kleines Problem:
Ich möchte zwei Ziffern, die hier drin stehen
ZahlenBuffer resb 0xF
addieren und in
resb Ergebnis 0xF
schreiben. Bekomme dies aber nicht hin. Muss ich die einzelnen Ziffern erst vom "Bytemodus" - also mit minus 0x30, ist die Null im ASCII-Code - in normal konvertieren und dann addieren oder hat jemand anderes eine Idee?
Danke für eine Idee schonmal!
-
ich bin mir nicht sicher ob ich dich richtig verstanden habe.
dein puffer ist 16 bytes groß. ich gehe also davon aus, dass
du jetzt zwei einzelne 4-byte werte darin gespeichert hast
die du addieren möchtest?!
wie dem auch sei, in diesem falle musst du erst den ersten operanden
in ein register kopieren, da 'add' keine speicher/speicher operanden
erlaubt. alsomov eax, ZahlenBuffer add eax, ZahlenBuffer+4 mov Ergebnis, eax
wie gesagt, dies hängt aber vollkommen davon ab, wie du die zahlenwerte
tatsächlich im puffer gepeichert hast, und vor allem wie breit sie sind.
-
Noch besser: Es sind nur 15 Byte je Puffer.
Klingt fuer mich fast so, als haette er 2 Strings mit dezimalzahlen, die er addieren will... Allerdings will sich mir auch nicht erschliessen, wie das nun in diesem Puffer abgelegt ist.
Falls dem so sein sollte: Zahl -> String (der Thread ist sogar noch auf der 1. Seite)
-
Nobuo T schrieb:
Noch besser: Es sind nur 15 Byte je Puffer.
doh!
passiert mir immer wieder
-
Also, ich habs hinbekommen: man ließt die Adresse des Strings in ein Register ein z.B. ebx und gibt den Inhalt von [ebx] in ein anderes Register ax. Nun subtrahiert man von al und ah die 0x30 (ASCII-Code entfernen) und addiert al mit ah. Das Ergebnis addiert man wieder mit 0x30 und gibt dieses wieder aus.
Ich kann den Code morgen mal komplett reinstellen, komm bloß grad ne daran.
Nun wieder en kleines Problem mit dem NASM:
Ich möchte den Stack benutzen, assemblieren und linken lässt sich das Programm, aber es kommt eine Fehlermeldung "Speicherzugriffsfehler" beim Ausführen des Programmes!
Hier der Code:
section .data section .text global _start _start: ;Teststack Teststack push ebp mov ebp, esp ;... mov esp, ebp pop ebp ret ;aufrufen call Teststack ;Programm beenden mov eax, 1 mov ebx, 0 int 0x80
-
Ist das wirklich der komplette Code? Schau dir das nochmal ganz genau an, ist wirklich ziemlich offensichtlich.
-
Also, ich kann nix entdecken, außer vielleicht der eine Doppelpunkt, aber der ist glaub ich nicht der Fehler.
Gib ma bitte nen Tipp ich sehs echt nich.
Dankeschön!
-
... Dann will ich dir mal etwas auf die Spruenge helfen...
section .data section .text global _start _start: ; Hier startet das Programm ;Teststack Teststack ; Beim Erstellen: Warnung: orphan label (-> da gehoert ein Doppelpunkt hinter) push ebp ; Hier geht's weiter: Erster Befehl, der ausgefuehrt wird mov ebp, esp ;... mov esp, ebp pop ebp ; praktisch hat sich bis hier nichts weiter getan... ret ; Ab ins Nirvana: Die Zieladresse auf dem Stack ist hier undefiniert! -> "Speicherzugriffsfehler" ;alles Folgende wird nie ausgefuehrt... ;aufrufen call Teststack ;Programm beenden mov eax, 1 mov ebx, 0 int 0x80
-
Alles klar, jetzt hab ichs verstanden, ich mach jetzt einfach nen Sprung über das TestStack bzw. schreib den TestStack ganz unten hin.
Dankööö!
-
Palim palim!
Da bin ich wieder mit der nächsten Frage: Ich möchte mit Hilfe der cpuid-Instruktion den Herstellernamen auslesen und das alles in NASM.
Hab mich schon ein wenig belesen:
http://de.wikipedia.org/wiki/CPUID
http://www.sandpile.org/ia32/cpuid.htmSo, also ich muss ins EAX den Wert 0 übergeben und dann Interrupt ausführen? Aber welchen? Ist das auch der 0x80? Resultat ist ein 12 Zeichen langer Name des Herstellers und zwar in den Registern ebx, ecx, edx verteilt (3*4=12 Bytes). Aber irgendwie funktioniert das nich.
Hat jemand ne Idee?
-
Keinen Interrupt. cpuid ist ein Prozessorbefehl - den schreibst du einfach so in dein Programm.
-
Aber irgendwie bekomm ichs trotzdem nicht hin...
Hier mal der Quellcode:
section .data Vendor db 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ;13 Byte Laenge equ $ - Vendor section .text global _start _start: ;Hersteller auslesen xor eax, eax ;Inhalte aus ebx, ecx, edx speichern mov [Vendor], ebx ;... die anderen Register ;Ausgabe mov eax, 4 mov ebx, 1 mov ecx, Vendor mov edx, Laenge int 0x80 ;Programm beenden mov eax, 1 mov ebx, 0 int 0x80
-
... Was erwartest du denn von diesem Code fuer eine Funktion? Meinst du, die CPU-ID wird ohne den cpuid-Befehl aus dem Nichts generiert, wann immer du eax auf 0 setzt?
-
Nein, das habe ich nicht erwartet, aber wenn ich keinen Interrupt ausführen muss, was dann? Muss ich irgendein Schlüsselwort "cpuid" einsetzen und wo? Ich weiß nich wie ich an die Information komme...
-
NASM schrieb:
Nein, das habe ich nicht erwartet, aber wenn ich keinen Interrupt ausführen muss, was dann? Muss ich irgendein Schlüsselwort "cpuid" einsetzen und wo? Ich weiß nich wie ich an die Information komme...
.< ok, jetzt versuch ich es mal mit farbe zu erkären
cpuid ist eine instruktion wiemov
oder
add
oder
xor
daraus folgt also
cpuid
im code genauso zu verwenden wie andere instruktionen. welche parameter in welchen registern erwartet werden kannst du in den prozessorspezifikationen nachlesen, ebenso in welchen registern aufrufresultate liegen.
-
Ok, jetzt hab ich verstanden. War ja ganz einfach :))
Danke!!!