As a preface, I'm running this on a 64-bit Linux OS and am thus using the 64-bit Linux syscalls.
My strlen procedure takes rdi as a parameter and returns the length of the string excluding \0 in rax. (You have to enter a string that ends with \0). I have tested this procedure and know it works correctly.
My puts procedure takes rdi as its parameter, uses strlen to get the length and then uses the write syscall.
Here is a (hopefully) minimal reproducible example:
section .data
msg db "HELLO", 10, 0
section .text
global _start
_start:
mov rdi, msg
call puts
mov rax, 0x3c
xor rdi, rdi
syscall
strlen:
push rdi
push rcx
push rsi
xor rax, rax
mov rcx, 0xffffffff
repnz scasb
jnz .error
not rcx
dec rcx
mov rax, rcx
.return:
pop rsi
pop rcx
pop rdi
ret
.error:
mov rax, -1
jmp .return
puts:
mov rsi, rdi
call strlen
mov rdx, rax
mov rax, 1
mov rdi, rax
syscall
ret
I'm really confused as to why this isn't working. My puts procedure is just a simple syscall really, so I honestly don't know what is going wrong here.
I have tested [my
strlen] and know it works correctly.
I'm afraid not.
mov rcx, 0xffffffff
You seem to be thinking this loads rcx with -1, but it doesn't: 0xffffffff is -1 as a 32-bit signed integer, but rcx is a 64-bit register. (Maybe you copied from some 32-bit code?) In particular, mov rcx, 0xffffffff followed by not rcx does not result in rcx containing 0, but rather 0xffffffff00000000. As a result your strlen returns a seriously incorrect value.
Change this to mov rcx, -1 or mov rcx, 0xffffffffffffffff.
User contributions licensed under CC BY-SA 3.0