AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

[MASM] strlen Funktion

Ein Thema von ferby · begonnen am 23. Jan 2009 · letzter Beitrag vom 13. Aug 2009
Antwort Antwort
Seite 1 von 2  1 2      
ferby

Registriert seit: 15. Aug 2004
Ort: Wien
841 Beiträge
 
Delphi 2010 Enterprise
 
#1

[MASM] strlen Funktion

  Alt 23. Jan 2009, 21:07
Hallo,

Hoffentlich kennt sich hier wer mit MASM aus

Also ich habe gerade angefangen MASM zu lernen und scheiter daran, eine Funktion zu schreiben,
die wie die strlen in C funktioniert. (Gibt die Anzahl der Bytes von der Startadresse bis zum ersten 0-Byte zurück)

(Ich möchte keine fertige strlen Version, sondern wissen warum meine Version nicht geht)

Also ich habe sogar zwei verschiedene Funktionen. Beide funktionieren manchmal und manchmal nicht (bei beiden
tritt immer der Fehler beim selben Teilstring auf)

...und ich habe keine Ahnung warum


Der Rückgabewert, also die Länge, steht am Ende in cx drin

Version 1:

Code:
STRLEN_DATA_TO_CX macro
   xor cx, cx
   dec ax

@@:
   inc ax
   inc cx
   cmp   DATA[eax], 0
   jnz @B

   dec cx
endm
Version 2:
Code:
STRLEN_DATA_TO_CX macro
   xor cx,cx

   .WHILE DATA[eax] != 0
      inc cx
      inc eax
   .ENDW
endm

Wobei in eax die Startadresse drin steht (immer nach 0501) und DATA so definiert ist:

Code:
DATA db 05,01,"aaa1a",00, 05,01,"a2a",00, 05,01,"3cd",00, 04,01
Ich nehme mal an ich habe hier einen Denkfehler


Falls ihr aus den Codeschnippsel jetzt nicht schlau werdet^^,
hier das ganze Programm (aber ich nehm an der Fehler liegt in den Codeschnippsel)

Code:
;                           ### COMPILER EINSTELLUNGEN ###
.386
.model flat,stdcall
option casemap:none
;                           ### BENÖTIGTE INCLUDES ###
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\gdi32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\gdi32.lib

INC_DATA_POINTER macro _add
   xor eax,eax
   add DATA_POINTER, _add
   mov ax,DATA_POINTER
endm

;STRLEN_DATA_TO_CX macro
;   xor cx, cx
;   dec ax

;@@:
;   inc ax
;   inc cx
;   cmp   DATA[eax], 0
;   jnz @B

;   dec cx
;endm

STRLEN_DATA_TO_CX macro
   xor cx,cx

   .WHILE DATA[eax] != 0
      inc cx
      inc eax
   .ENDW
endm

.data

DATA_POINTER dw 0                            ; Speichert die aktuelle Position im DATA String
Error db "Es ist leider ein interner Fehler aufgetreten :-(",10,10,0
AppNameDefault db "FD3",0

; ### ZUM TESTEN ###
DATA db 05,01,"aaa1a",00, 05,01,"a2a",00, 05,01,"3cd",00, 04,01

.code
START:
   .WHILE TRUE
                ; Lösche EAX und Speicher den aktuellen Wert des DATA_Pointer
                xor eax, eax
                mov ax, DATA_POINTER

                ; ##########
                ; REGISTER 1
                .IF DATA[eax] == 4

                    INC_DATA_POINTER 1

                    ;4/1
                    .IF DATA[eax] == 1
                        invoke ExitProcess,0
                    .ENDIF

                ; ##########
                ; REGISTER 5
                .ELSEIF DATA[eax] == 5
                    INC_DATA_POINTER 1

                    ;5/1
                    .IF DATA[eax] == 1
                        INC_DATA_POINTER 1
                        invoke MessageBox, 0, ADDR DATA[eax], ADDR AppNameDefault, MB_OK
                        STRLEN_DATA_TO_CX
                        INC_DATA_POINTER cx
                    .ENDIF

                ; #####
                ; ERROR
                .ELSE
                    invoke MessageBox, 0, ADDR Error, ADDR AppNameDefault, MB_OK
                    invoke ExitProcess, 0
                .ENDIF
   .ENDW

   invoke ExitProcess,0

END START
Das Programm soll nichts anderes tun als drei Message Boxes auszugeben mit dem Inhalt:
aaa1a
a2a
3cd

und sich dann beenden.

Die ersten zwei Messages Boxes werden ausgegeben, bei der dritten gibt auf einmal STRLEN einen falschen wert zurück !?

(Nich über das Programm wundern, lern grad erst ASM und schreib irgendwas zum ausprobieren^^)


vielen dank falls sich wer die Zeit nimmt mir weiter zu helfen,


Lg,
Ferby
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 11:08
ist dir schon aufgefallen, daß du auf meißt nur AX setzt und mit EAX prüfst?

Code:
STRLEN_DATA_TO_CX macro
   @@loop:
   inc eax      <<<<< hier
   inc cx
   cmp DATA[eax], 0
   jnz @@loop
   dec cx
endm
was glaubst du denn, was passiert, wenn beim weiterechnen die WORD-Grenze überschritten wird?

z.B.
String fängt an Adresse $0040fff8 an und ist 32 Zeichen lang
dann ergibt das eine schöne Endlosschleife,
denn die #0 ist dann an Adresse $00410018, aber da nur AX geändert wird, kommst du nur an Adresse $00400018 vorbei.

Code:
STRLEN_DATA_TO_CX macro
   xor cx, cx
   cmp eax, 0    // prüfen ob EAX = nil
   jz @@end    //

   @@loop:
   inc eax
   inc cx
   cmp DATA[eax], 0
   jnz @@loop
   dec cx
   @@end:
endm
$2B or not $2B
  Mit Zitat antworten Zitat
ferby

Registriert seit: 15. Aug 2004
Ort: Wien
841 Beiträge
 
Delphi 2010 Enterprise
 
#3

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 12:08
Hallo,

Thx für deine Antwort.

So was in der Art dachte ich mir schon, muss mir das glaub ich aufzeichnen damit ich das ganz check

Was ich auch noch nicht ganz kapiert hab:
wenn ich sag ma in eax den Wert 54353 Speicher und in ebx den Wert 354636
wie weiß jetzt der cmp Befehl ob ich die Werte 54353 und 354636 vergleichen will oder
ob in eax und bax zwei Adressen auf zb zwei Chars im Arbeitsspeicher sind, und ich möcht eigentlich die zwei Chars vegleichen??!
Das habe ich auch noch nicht ganz überissen.
Vlt kannst du mir das auch erklären.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 12:12
Um die beiden (Ansi-)Chars zu vergleichen, müsstest du folgenden Code ausführen:
Code:
mov cl, [ebx]
cmp cl, [eax]
Du musst also auch in Assembler manuell dereferenzieren.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
ferby

Registriert seit: 15. Aug 2004
Ort: Wien
841 Beiträge
 
Delphi 2010 Enterprise
 
#5

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 12:23
axo also eckige Klammer dereferenziert?


Eine letzte Frage noch

@@:
.....
jnz @B


Was bedeutet hier das @@ und warum spring ich genau mit @b dort hin.
Find das immer wieder in Beispielen, aber niegendst wirds erklärt.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 13:53
@xyz ist ein Sprungziel (entspricht Delphi-Referenz durchsuchenlabel in Delphi)

@@xyz ist das Selbe. Nur verwendet man meißtens für prozedurinterne Sprünge @@ und für den Rest @

Aber wenn du nicht weißt, warum du mit jnz @xyz dort hin springst, dann solltest du dir lieber mal gedanken machen und die Assemblergrundlagen lernen.

jnz = jump if not zero (wird über das entsprechende Register geprüft und dieses enthält das Ergebnis des vom vorherigen Vergleichs)
$2B or not $2B
  Mit Zitat antworten Zitat
ferby

Registriert seit: 15. Aug 2004
Ort: Wien
841 Beiträge
 
Delphi 2010 Enterprise
 
#7

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 14:38
Hallo,

sry, du hast glaub ich meine Frage falsch verstanden...

ich weiß was Labels sind, was jnz heißt und die Grundlagen hab ich auch so langsam drausen

ich versteh nicht warum der Label
@@ heißt aber ich mit @B dort hin springe.



Normal habe ich ja zb den Label Error und springe auch mit Error dort hin


tu was
jnz Error


Error :
tu was




meine Frage bezieht sich drauf, das ich diesmal

tu was
jnz @B

@@ :
tu was


stehen hab. Und das versteh ich nicht
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 14:47
nja, ist wohl alles mehr das selbe, aber mit @@xyz springst du zu @@xyz (hab oben grad gemerkt, daß ich da ein @ vergssen hatte )

und mit @xyz dann zu @xyz

mit @xyz dürfte es eigentlich nicht zu @@xyz springen


(dieses @ nimmt man mehr als Kennzeichnung der Labels ... der Übersichtlichkeit halber)

ist wohl ähnlich, bei beim Kennzeichnen einer Variable/Konstante mit & , fall der Name nicht eindeutig ist
(ich hab mir angewöhnt dieses & immer zu machen ... müßt ich theoretisch aber nicht, wollt es nur einheitlich haben)
Delphi-Quellcode:
const eax = 123;

asm
  @@mov:
  mov eax, &eax
  // entspricht
  mov eax, 123
  jmp @@mov
[edit] ach menno, immer diese Verschreiber
$2B or not $2B
  Mit Zitat antworten Zitat
ferby

Registriert seit: 15. Aug 2004
Ort: Wien
841 Beiträge
 
Delphi 2010 Enterprise
 
#9

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 17:29
Hallo,

nach ewigen herumprobieren und schließlich einen debugger bin ich auf den Fehler drauf gekommen.
Es lag eigentlich gar nicht daran das eine Word Grenze überschritten wird.

Der Fehler lag daran, das ich die aktuelle Position in eax Speicher.
Nach dem Aufruf von

Code:
invoke MessageBox, 0, ADDR DATA[eax], ADDR AppNameDefault, MB_OK
wird aber das eax Register überschrieben


Hier meine Überarbeitet strlen Funktion

Code:
STRLEN_DATA_TO_CX macro
   xor cx,cx

   xor eax,eax              <--- Neu, lösche überschriebenes eax Register
   mov ax, DATA_POINTER    <--- Neu, schreibe meine aktuelle Position wieder hinein

   .WHILE DATA[eax] != 0
      inc cx
      inc eax
   .ENDW

   inc cx              <--- Neu, +1 dazu, wegen dem 0 Byte vom Vorstring
endm
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

Re: [MASM] strlen Funktion

  Alt 24. Jan 2009, 18:36
jupp, da mußt du auch aufpassen.
EAX, ECX, EDX, EDI, ESI darfst du und jeder andre unkontrolliert verändern,
also beim Aufruf von anderen Prozeduren, solltest du dir die nötigen Felder sichern ... bzw. am Ende deiner Prozedur die sonstigen (hier nicht aufgezählten) Felder wieder herstellen.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz