Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: bscreator am 21. July 2007, 16:07
-
Hallo OS-Coder,
hab ein Problem mit LODSB sowie dem ganzen DS und DI-Zeug.
Ich schreib grad ne kleine Funktion, die alle Zeichen eines Strings in Grossbuchstaben konvertiert. Anschließend SOLL der umgewandelte String in einer neuen Funktion wieder ausgegeben werden.
Unten stehen die relevanten Codeausschnitte:
mov si, hallo
call ConvertBig
call WriteString
ret ;Programmende
ConvertBig:
lodsb ;Lädt nächstes Byte aus DS:SI
or al,al
jz short ConvertBig_End ;0-Byte? -> Ende
cmp al,0x61
jl short ConvertBig ;Kleiner als Kleinbuchstabenreihe ? -> zurück zum Anfang
cmp al,0x7A
jg short ConvertBig ;Größer als Kleinbuchstabenreihe? -> zurück zum Anfang
sub al,0x20 ;in Grossbuchstaben konvertieren
mov [DS:SI], al ;konvertiertes Zeichen zurückschreiben in DS:SI
jmp ConvertBig
ConvertBig_End:
retn
WriteString:
lodsb
or al,al
jz short WriteString_End
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp WriteString
WriteString_End
retn
Die Funktion WriteString funktioniert problemlos.
hallo ist ein normaler String ( hallo db 'Hallo',10,0 )
Der Befehl "lodsb" in ConvertBig lädt ein Byte in das über DS:SI adressierte Registerpaar nach AL. Anschließend wird geprüft, ob es sich um einen Kleinbuchstaben handelt. Wenn ja, wird dieser durch "sub 0x20, AL" in einen Grossbuchstaben umgewandelt und mit mov [DS:SI], AL zurückgeschrieben, wobei ich mir bei dieser Zeile nicht ganz sicher bin.
Beim Ausführen dieses Programms erscheint irgendein Mist auf dem Bildschirm.
Hab den Verdacht, dass das an SI liegt, welches nicht mehr auf den Stringanfang zeigt. Mit "mov si,ds" hab ichs versucht, ohne Erfolg.
Was muss ich zwischen "call ConvertBig" und "call WriteString" einfügen, um den neuen Grossbuchstabenstring auszugeben ?
Vielen Dank
bsc
-
mach mal statt mov [ds:si],al ein mov [ds:si -1],al hin...
Wie hast du das DirectionFlag gesetzt?
Gruss
Nooooooooos
-
Was muss ich zwischen "call ConvertBig" und "call WriteString" einfügen, um den neuen Grossbuchstabenstring auszugeben ?
Da LoadSB
mov al, [ds:si]
inc si
entspricht ziegt si am ende hinter das Ende von deinem String
als must du si neu mit der anfangsadresse laden
mov si, hallo
und wie no...os geschrieben hat
das
mov [ds:si],al
durch
mov [ds:si-1],al
ersetzen
-
mov si, hallo
call ConvertBig
mov si,hallo ;<-
call WriteString
ret ;Programmende
ConvertBig:
lodsb ;Lädt nächstes Byte aus DS:SI
or al,al
jz short ConvertBig_End ;0-Byte? -> Ende
cmp al,0x61
jb short ConvertBig ;Kleiner als Kleinbuchstabenreihe ? -> zurück zum Anfang
cmp al,0x7A
ja short ConvertBig ;Größer als Kleinbuchstabenreihe? -> zurück zum Anfang
sub al,0x20 ;in Grossbuchstaben konvertieren
mov [DS:SI-1], al ;<- konvertiertes Zeichen zurückschreiben in DS:SI
jmp ConvertBig
ConvertBig_End:
retn
WriteString:
lodsb
or al,al
jz short WriteString_End
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp WriteString
WriteString_End
retn
bitmaster
-
Vielen Dank, es funktioniert.
Ich muss sagen, dass ich ziemlich skeptisch war, als ich den Code von Bitmaster gelesen hab, weil ich, als ich das mov si,hallo
vor dem WriteString gesehen hab dachte, dass dann wieder das normale "Hallo" ausgegeben wird. Aber stimmt ja, mit mov si, hallo
wird nicht der Text, sprich das "Hallo" geladen, sondern lediglich die Speicheradresse.
Vielen Dank, hab wieder einiges gelernt
-
Ich hätte das ganze wohl mit dec si und stosb gelöst, aber jedem das Seine.
Oh und nochwas: solltest du den Code ganz oft verwenden wollen und dich hunderprozentig darauf verlassen, dann würde ich noch nach jedem lodsb testen, ob si überläuft. Also mit jc noch ein
push ax
mov ax, ds
add ax, 0x1000
mov ds, ax
pop ax
oder so anbringen.
-
Dann solltest du das aber am Ende der Funktion das ds auch wieder zurücksetzen. Mitten im Code ein anders ds macht auch keinen Spaß.