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