The MASM Forum Archive 2004 to 2012

Project Support Forums => 64 Bit Assembler => Topic started by: liamo1 on September 19, 2010, 07:56:12 PM

Title: translating strlen from Masm32 to 64bits
Post by: liamo1 on September 19, 2010, 07:56:12 PM
Hi all

I am using JWasm on vista 64bit and I am having a problem with the strlen procedure from masm32. Please see the code below

StrLen proc item:DWORD

    mov     rax, rcx             ; get pointer to string from one and only rcx
    lea     rdx, [rax+3]            ; pointer+3 used in the end
    push    rbp
    push    rdi
    mov     rbp, 8080808080808080h

  @@:     
  REPEAT 3
    mov     rdi, [rax]              ; read first 8 bytes
    add     rax, 8                  ; increment pointer by 8
    lea     rcx, [rdi-0101010101010101h]    ; subtract 1 from each byte      <==========Here
    not     rdi                      ; invert all bytes
    and     rcx, rdi                ; and these two
    and     rcx, rbp
    jnz     nxt
  ENDM

    mov     rdi, [rax]              ; read first 8 bytes
    add     rax, 8                  ; 8 increment QWORD pointer
    lea     rcx, [rdi-0101010101010101h]    ; subtract 1 from each byte     <=========Here
    not     rdi                      ; invert all bytes
    and     rcx, rdi                ; and these two
    and     rcx, rbp
    jz      @B                      ; no zero bytes, continue loop

  nxt:
    test    rcx, 0000000000008080h          ; test first two bytes
    jnz     @F
    shr     rcx, 16                  ; not in the first 2 bytes
    add     rax, 2
  @@:
    shl     cl, 1                    ; use carry flag to avoid branch
    sbb     rax, rdx                ; compute length
    pop     rdi
    pop     rbp

    ret

StrLen endp


The error I get is constant too large where lea is used above. Can anyone explain what I am doing wrong?

Liam
Title: Re: translating strlen from Masm32 to 64bits
Post by: tofu-sensei on September 20, 2010, 09:42:15 AM
You can only use 64-bit immediates by moving them directly into a register.
By the way, there is no need to save rbp and rdi - just use some of the 'new' registers instead.
Title: Re: translating strlen from Masm32 to 64bits
Post by: liamo1 on September 20, 2010, 04:31:37 PM
Thanks tofu-sensei but if I mov the constant into a register say r9 and then try lea rcx, [rdi-r9] i get the error constant expected.

Liam
Title: Re: translating strlen from Masm32 to 64bits
Post by: liamo1 on September 20, 2010, 06:40:14 PM
Its a bug in JWasm that is still open for 64 bit progs. It assembles correctly with ml64.

Liam
Title: Re: translating strlen from Masm32 to 64bits
Post by: clive on September 20, 2010, 08:06:12 PM
Quote from: liamo1 on September 20, 2010, 04:31:37 PM
lea rcx, [rdi-r9] i get the error constant expected

Can LEA perform subtractions? I think not, it can do it for "constants" because the assembler performs a twos-complement of the number.

You probably should negate R9 or (MOV R9,-0101010101010101h in this case), and use LEA RCX,[RDI+R9]
Title: Re: translating strlen from Masm32 to 64bits
Post by: japheth on September 21, 2010, 05:51:09 AM
Quote from: liamo1 on September 20, 2010, 06:40:14 PM
Its a bug in JWasm that is still open for 64 bit progs. It assembles correctly with ml64.

I'd rather say that Masm assembles is without error messages. If the result is "correct" depends on how you define this term. I'm no expert for 64-bit, but AFAIK displacements are still restricted to 32-bit in long mode - and displacements are the only type of "offsets" which LEA will accept.