assemblyx86-64attrelocation

Relocation truncated error in assembler


I'm totaly new to assembly language. I tried to make simple program to decipher a Caesar cipher. The problem is that after linking I get these errors:

cezar.o: In function `loop':
(.text+0xbf): relocation truncated to fit: R_X86_64_8 against `.data'
cezar.o: In function `check_letter': 
(.text+0xd5): relocation truncated to fit: R_X86_64_8 against `.data'

I'll be honest - I have no idea what this means. Can anybody help me? Rather, #explainMeLikeI'm5 ;P

My code if neded:

.data
STDIN = 0
STDOUT = 1
SYSWRITE = 0
SYSREAD = 1
SYSEXIT = 60
EXIT_SUCCESS = 0
BUFLEN = 512
BASE = 10
BASE_NUM = 10
BASE_CHAR = 26
NUM_BEG = 48

error_msg: .ascii "Bad characters in key\n"
error_msg_len = .-error_msg

key: .ascii "-128"
key_len = .-key

.bss
.comm textin, 512
#.comm keyin, 512
.comm textout, 512

.text
.globl _start

_start:
#check if key is good
movq $0, %rdi
movb key(, %rdi, 1), %bl    #load first char to bl
cmp $'-', %bl           #check if it's -
jne error
movq $1, %rdi           #counter
movb key(, %rdi, 1), %bl 
cmp $'0', %bl           
jl error                
cmp $'9', %bl           
jg error

mov $key_len, %rdi
mov $1, %r11            #powers of 10
mov $0, %r8             #calculated key goes to r8
sub $1, %rdi            #because I want numbers only, "-" doesn't interest me now

ascii_to_num:
cmp $1, %rdi            #at rdi=0 jump out of loop
jl load_text        

mov $0, %rax            #clearing rax
mov key(, %rdi, 1), %al 
sub $NUM_BEG, %al       
mul %r11                #multiplying al by power of it's position
add %rax, %r8           

mov %r11, %rax          
mov $10, %r12       
mul %r12                
mov %rax, %r11          

dec %rdi                #decrementation
jmp ascii_to_num        


load_text:
movq $SYSREAD, %rax     
movq $STDIN, %rdi       
movq $textin, %rsi      
movq $BUFLEN, %rdx      

dec %rax                #delete '\n'
movq %rax, %r10         

movq $0, %rdi           #counter
loop:
movb textin(, %rdi, 1), %bh 
                        #check if number
movb $'0', %bl          #I'm using bl for comparing
cmp %bl, %bh            
jl ending_loop          
movb $'9', %bl
cmp %bl, %bh            
jg check_letter         
add $key, %bh           
cmp $'0', %bh
jl correct_num
jmp ending_loop

check_letter:
movb $'A', %bl
cmp %bl, %bh            
jl ending_loop          
movb $'Z', %bl
cmp %bl, %bh            
jg ending_loop          
add $key, %bh           
cmp $'A', %bh   
jl correct_char 
jmp ending_loop

correct_num:            
add $BASE_NUM, %bh
cmp $'0', %bh
jl correct_num
jmp ending_loop

correct_char:       
add $BASE_CHAR, %bh
cmp $'A', %bh
jl correct_char
jmp ending_loop

ending_loop:
movb %bh, textout(, %rdi, 1)
inc %rdi
cmp %r10, %rdi
jle loop
jmp show

error:                  #error message
mov $SYSWRITE, %rax
mov $STDOUT, %rdi
mov $error_msg, %rsi
mov $error_msg_len, %rdx
syscall

show:                   #display message and close programm
add $'\n', textout
mov $SYSWRITE, %rax
mov $STDOUT, %rdi
mov $textout, %rsi
mov $BUFLEN, %rdx
syscall

mov $SYSEXIT, %rax
mov $EXIT_SUCCESS, %rdi
syscall

Solution

  • The errors refer to the two lines where you wrote:

    add $key, %bh
    

    This tries to add the value of key (i.e. the address of the string -128) to bh. As the address is larger than 255, it does not fit into a byte register like bh. For this reason, you get the error indicated by the linker.

    I have not analyzed what you try to do by loading the address of key into bh, but doing so is not going to work. If you want to load the first byte of the data at key, write

    add key(%rip), %bh
    

    If you want to load the address of key, you need to load it into a 64 bit register using lea like this:

    lea key(%rip), %rbx