Assembler und UTF-8

Hallo,

ich bin Neuling in der Assemblerprogrammierung und mir wurde die Aufgabe gestellt, in einem gegebenen String bei der Ausgabe ä,ü,ö durch ae,ue,oe zu ersetzen.

Unter Windows funktioniert das ganze, ich muss jedoch Linux für diese Aufgabe nutzen. Mein Problem ist, dass ich das Ende des Stings mit einem $ markieren und durch cmp erkennen lassen möchte.

Das Problem:
Das Programm sagt dass cmp [register],’$’ ungleich ist obwohl das zeichen $ in das Register geladen wurde.
Ein Blick in den Debugger sagt mir dann, dass das $ aus dem String den HexCode 0x6124 habe, das zu vergleichende $ aber 0x61.

Kann mir jemand sagen wo der Fehler liegt? Hier ist das Programm was ich geschrieben und mit NASM assembliert habe.

;Übung 1 - Aufg3
;Notizen:
;Achtung! Bei UTF-8 Systemen sind Umlaute 2 Byte lang
;int 0x80 scheint die Register EAX und EBX nach Aufruf zu verändern!

section .data
 string DB "Häuser Löcher Süss$"
 s\_ae DB "ae"
 s\_ue DB "ue"
 s\_oe DB "oe"

section .text
 global \_start

\_start :

 ;Anfangswerte
 mov ecx, string ;Adresse des Strings

wh: ;prüfen
 xor edi, edi 
 mov di, [ecx] ;Inhalt von ecx nach DI 
 mov esi, s\_ae ;SI falls Ausg von Umlaut -\> nur eine Unterfunktion nötig 
 cmp di, 'ä'
 je uml
 mov esi, s\_ue
 cmp di, 'ü'
 je uml 
 mov esi, s\_oe
 cmp di, 'ö'
 je uml
 mov esi, '$' ;!! Ergibt im Debugger 0x24
 cmp di, '$' ;!! DI aus String ist aber angeblich 0x6124
 je ende

 ;normale Ausgabe 
 mov eax, 4
 mov ebx, 1
 mov edx , 1
 int 0x80

 ;Zeiger erhöhen und springen
 add ecx, 0x01
 jmp wh

uml: mov eax, 4
 mov ebx, 1
 mov edi, ecx ;ECX in EDI sichern
 mov ecx , esi
 mov edx , 2
 int 0x80

 ;ECX rücksichern, Zeiger erhöhen und springen (Uml 2 Byte!)
 mov ecx, edi 
 add ecx, 0x02
 jmp wh

ende: ; Programm beenden
 mov eax , 1
 mov ebx , 0
 int 0x80

Das Programm sagt dass cmp [register],’$’ ungleich ist obwohl
das zeichen $ in das Register geladen wurde.
Ein Blick in den Debugger sagt mir dann, dass das $ aus dem
String den HexCode 0x6124 habe, das zu vergleichende $ aber
0x61.

Hallo,

meine Vermutung ist, dass in der Eingabe-Datei und dem Assember-Editor verschiedene Codepages verwendet werden:

http://de.wikipedia.org/wiki/Codepage
http://de.wikipedia.org/wiki/Unicode

Grüße
Thorsten

Hallo Fragewurm,

ich bin Neuling in der Assemblerprogrammierung und mir wurde
die Aufgabe gestellt, in einem gegebenen String bei der
Ausgabe ä,ü,ö durch ae,ue,oe zu ersetzen.

Dein Problem ist, das UTF-8 keine feste Länge für Zeichen kennt:
http://de.wikipedia.org/wiki/UTF-8

Du musst also zuerst die höchstwertigen Bits auswerten um zu wissen wie viele Bits ein Zeichen hat.
Erst dann kannst du vergleichen !

Dein Programm geht jetzt einfach stur davon aus, dass ein Zeichen 2 Byte lang ist …

Unter Windows hat es wohl funktioniert, weil Windows UTF -16 verwendet, da sind die Zeichen immer 2 Byte Lang.

MfG Peter(TOO)

Hallo

Ich habe folgende Zeile gefunden:
mov di, [ecx] ;Inhalt von ecx nach DI
Der richtige Kommentar hieße wohl: „Inhalt des Speichers ab der Adresse in ecx nach di kopieren“
Das meintest Du wohl auch, aber hier ist nicht definiert, ob Du ein Byte, ein Word oder gar versuchst, 32 Bit (DWord) zu kopieren.
di nimmt jedenfalls als 16 Bit Register 2 Byte, bzw. das ist ein Word, auf.
Um nun garantiert nur ein Byte zu kopieren, das ist wohl Dein Problem, nimmst Du entweder ein Byteregister, das ist z.B. al, bl , cl, dl, dasselbe mit h sollte auch gehen, oder du definierst den Pointer mit BytePtr. So gehts jedenfalls bei masm.
Mit solchen Fehlern ist man übrigens stark in der Lernphase beschäftigt.
Das Program als ganzes habe ich nun aber noch nicht analysiert.
MfG
Matthias