News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Strlen

Started by ferby, January 23, 2009, 08:18:32 PM

Previous topic - Next topic

ferby

Hello,

i'm from Austria, so my english might be very bad^^

But i think you will understand my problem.

I try too write a function like the strlen function in C. But it works only sometimes.

I don't want a strlen function from you, i want to know why my function does not work.

Can you help me?

This programm shoul show three messages
aaa1a
a2a
3cd
and then close.

The first 2 messages are shown, but then my strlen function returns a false value, i have no idea why....




; ### 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

; THIS FUNCTION ALSO NOT WORK
;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 "ERROR!!!!!",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



korte

WHILE DATA[eax] != 0

byte? word? dword?

ferby

ups, i mix data types. thx, i willl try to correct it

qWord

hi,

Quote from: ferby on January 24, 2009, 12:46:50 PM
ups, i mix data types. thx, i willl try to correct it
that's not the problem! DATA is declared as Byte

here some problems:
- MessageBox() change the content of eax and ecx - reload it after call.
- xor cx,cx deletes only the lower 16bit , not the higher ones
- your routine ignores the terminating-zero.

---

some tips:
- do not use partial registers (only if necessary)
- write a function (e.g. szLenA proc lpString:DWORD ...) instead of a macro
- use a pointer instead of an index (DATA_POINTER).


regards, qWord
FPU in a trice: SmplMath
It's that simple!

RuiLoureiro

Hi ferby,
             your problem seems to be solved
This works

.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
   movzx eax,DATA_POINTER
endm

STRLEN_DATA_TO_CX macro
   xor ecx,ecx

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

.data

DATA_POINTER dw 0          ; Speichert die aktuelle Position im DATA String
Error db "ERROR!!!!!",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
                movzx    eax, 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

                        push    eax
                        invoke MessageBox, 0, ADDR DATA[eax], ADDR AppNameDefault, MB_OK
                        pop     eax
                       
                        STRLEN_DATA_TO_CX

                        INC_DATA_POINTER 1        ; because null terminator

                        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