This is my minimal code example.
I am trying to basically print one string from array of strings.
And I think relocation destroys me here.
This is my example, sorry about formatting, I am typing this by hand:
global start
sys_exit equ 0x01
sys_write equ 0x04
stdout equ 0x01
%define sys syscall
section .text
start:
; ok lets print one message, it works of course
lea rdi, [rel message_one]
call print_c
; ok, now lets print message from array
; lets use rax as an index of array
mov rax, 0
shl rax, 3 ; pointers are 8 bytes long
lea rdi, [rel message_array]
add rdi, rax
mov rdi, [rdi]
call print_c
mov rax, sys_exit
sub rdi, rdi
sys
print_c:
push rax
push rcx
push rdx
push rdi
push rsi
push r11
cld
sub ecx, ecx
push rdi
dec rcx
sub eax, eax
repnz scasb
pop rsi
mov rdx, rcx
add al, sys_write
not rdx
sub edi, edi
dec rdx
inc edi
sys
pop r11
pop rsi
pop rdi
pop rdx
pop rcx
pop rax
ret
section .data
message_one:
db 'This is the first message.', 0x0a, 0x00
message_two:
db 'This is the second message.', 0x0a, 0x00
message_three:
db 'This is the third message.', 0x0a, 0x00
message_array:
dq message_one
dq message_two
dq message_three
section .note.openbsd.ident
align 2
dd 8, 4, 1
db 'OpenBSD', 0
dd 0
align 2
build
nasm -o example.o -f elf64 example.s
ld.bfd -e example -e start -static example.o
This segfaults of course, the wrong address is put in rdi at the end of second print example.
How to do this correctly? What am I missing?
Sorry about typos if there are some, I typed it by hand, but the example is simple enough.
Thanks.