0

I am trying to write a procedure to find the length of a null-terminated string and store the length in eax. The start address of the string is stored in edx before calling the procedure.

Here's my code, I don't know what's wrong:

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD

.data
myString BYTE "Hello programmers", 0


strLength PROC
mov eax , 0
mov ebx , '/0'
mov esi , 0
Condition:
movzx ecx , myString[esi]
cmp ebx , ecx
je ExitLoop
inc esi
inc eax
jmp Condition
ExitLoop:
ret
StrLength ENDP



main PROC
lea edx, myString
call strLength 

INVOKE ExitProcess,0
main ENDP
END main

Here's the error message I'm getting:

error

Line 14 is : Condition
Line 21 is : ExitLoop:
Line 17 is : je ExitLoop
Line 20 is : jmp Condition
Line 29 is : call strLength
Line 38 is : INVOKE ExitProcess,0
and line 70 doesn't exist

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Seba
  • 21
  • 8
  • 1
    Please show us the error message. What I can see is a typo in `call strLength` which should be `call StrLength`. – xiver77 Mar 02 '22 at 17:27
  • 2
    You're code should work fine, but you don't need to maintain two counters, and you can `cmp` with an immediate `0`, or `test ecx, ecx`. – xiver77 Mar 02 '22 at 17:29
  • 2
    `'/0'` looks wrong. Did you mean to use `'\0'`'? (which of course can be replaced with just `0`). – Michael Mar 02 '22 at 17:34
  • @xiver77 can you check it now please – Seba Mar 02 '22 at 17:40
  • 3
    Don't put code in the data section. You need a `.code` directive. – Michael Mar 02 '22 at 17:40
  • @Michael even when I use 0 I still get the same list of errors – Seba Mar 02 '22 at 17:41
  • @Michael now it's working thank you so much – Seba Mar 02 '22 at 17:42
  • Sort of a duplicate of [segmentation fault with .text .data and main (main in .data section)](https://stackoverflow.com/q/34350582) in that the problem is the same, but the symptoms are very different with MASM refusing to assemble it, vs. other assemblers just assembling the same way regardless of section. – Peter Cordes Mar 03 '22 at 02:11
  • Also, this is of course quite inefficient. You are doing one good thing, though, loading with `movzx` instead of `mov cl , myString[esi]`. But wait a minute, you're hard-coding the symbol name into the loop? Why do you have 2 counters that both start at zero? It would have made some sense to have one pointer increment and one counter increment, but when the index and counter are always the same, that's just obvious duplication of work. – Peter Cordes Mar 03 '22 at 02:16
  • Byte-at-a-time is much slower than strlen has to be ([Why does glibc's strlen need to be so complicated to run quickly?](https://stackoverflow.com/a/57676035)), but if you are going to do that, [Return a pointer at a specific position - Assembly](https://stackoverflow.com/a/71199332) shows a good `strchr` loop that does a pointer-increment inside the loop. Replace the `cmp cl, sil` with `cmp cl, 0` or `test ecx, ecx` and it's a strlen instead of strchr. (And subtract the pointer at the end, to return a length instead of a pointer to the terminating 0.) – Peter Cordes Mar 03 '22 at 02:16

0 Answers0