我使用nasm(64位)重新编码put,当puts接收NULL作为参数时,它打印(null)。我试图重新创建这种行为,除了我无法将代码跳转到打印的部分(null)。相反,它只是打印任何东西
这是我的代码:
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
我也试过
test rdi, rdi
je is_null
没有变化。有什么想法吗?
感谢您的帮助:)
答案 0 :(得分:2)
您的第一条指示是问题:cmp rdi, 0
。您将传递给my_puts
的字符串指针与值0进行比较,以确定是否应该打印"(null)"而不是将字符串的第一个字节与0进行比较。我假设您传递0指针,那将是一个错误。
尝试:
_my_puts:
mov r8, rdi
cmp [r8], 0
je is_null
print_and_add:
...
如果你想对0指针进行防御性检查,你也可以包括它,但你不会检查任何其他坏指针:
_my_puts:
cmp rdi, 0
je bad_pointer
mov r8, rdi
cmp [r8], 0
je is_null
print_and_add:
...