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
WHILE DATA[eax] != 0
byte? word? dword?
ups, i mix data types. thx, i willl try to correct it
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
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