translating strlen from Masm32 to 64bits

Started by liamo1, September 19, 2010, 07:56:12 PM

Previous topic - Next topic

liamo1

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

tofu-sensei

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.

liamo1

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

liamo1

Its a bug in JWasm that is still open for 64 bit progs. It assembles correctly with ml64.

Liam

clive

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]
It could be a random act of randomness. Those happen a lot as well.

japheth

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.