I am recoding puts using nasm (64bit), and when puts receives NULL as argument it prints (null). I'm trying to recreate that behaviour, except I can't get the code to jump to the part where it prints (null). Instead it just prints nothing
here's my code:
global _my_puts
section .text
%define WRITE 0x2000004
%define STDOUT 1
_my_puts:
cmp rdi, 0
je is_null
mov r8, rdi
cmp byte [r8], 0
jne print_and_add
print_and_add:
mov rax, WRITE
mov rdi, STDOUT
mov rsi, r8
mov rdx, 1
syscall
inc r8
cmp byte [r8], 0
jne print_and_add
mov rax, WRITE
mov rdi, STDOUT
mov rdx, newline.len
lea rsi, [rel newline]
syscall
mov rax, 1
ret
is_null:
mov rax, WRITE
mov rdi, STDOUT
lea rsi, [rel nullmsg]
mov rdx, nullmsg.len
syscall
mov rax, 1
ret
section .data
nullmsg: db "(null)", 10
.len: equ $ - nullmsg
newline: db 10
.len: equ $ - newline
I also tried
test rdi, rdi
je is_null
with no change. Any ideas?
thanks for the help :)
Your first instruction is the problem:
cmp rdi, 0
. You're comparing the string pointer, passed tomy_puts
, to the value 0 to determine if you should print "(null)" rather than comparing the first byte of the string to 0. I'm supposing if you pass a 0 pointer, that would be an error.Try:
If you want the defensive check against a 0 pointer, you could include that as well, but you wouldn't be checking against any other bad pointers: