релокация усечена, чтобы соответствовать: R_386_8 против '.rodata'

Я получил эту ошибку при попытке скомпилировать простую функцию смены регистра строк в сборке x86 AT&T.

Я попытался просмотреть другие вопросы с этой ошибкой, но ни один из них не был достаточно похож, чтобы помочь в моем случае. Большинство из них имели дело с вещами в разных библиотеках и файлах, чего здесь нет.

Ошибка:

$ gcc -m32 -g main.c test.s -o Test4
/tmp/ccQ49nKM.o: In function `scLOOP':
/home/nikolay/Dropbox/comporg/ex3/solution/test.s:24:(.text+0x14): relocation truncated to fit: R_386_8 against `.rodata'
collect2: error: ld returned 1 exit status

Код:

    .section .rodata
.align      4
error:      .string "invalid input!\n"  # error message.
a:      .byte   97          #a in ascii.

    .text

    .global swapCase        #swaps the cases of the string.
    .type   swapCase, @function
swapCase:
    pushl   %ebp            #save old FP
    movl    %esp, %ebp      #set new FP

    movl    8(%ebp), %eax       #get pointer to pstring
    movb    (%eax), %cl     #get length of pstring
    addl    $1, %eax        #move pointer to string itself

    scLTEST:            #loop condition.
    cmpb    $0, %cl         #compare length with 0
    je  scDONE          #if length is zero, goto done
    jmp scLOOP          #else: goto loop

    scLOOP:
    cmpb    $a, (%eax)      #compares first byte of string with a='a'.
    jl  scTOLOWER       #byte is uppercase.
    subb    $32, (%eax)     #byte is lowercase, change to uppercase.
    jmp scINC           #increment pointer.
    scTOLOWER:
    addb    $32, (%eax)     #change to lowercase.
    jmp scINC           #increment pointer.

    scINC:
    addl    $1, %eax        #increment %eax to next byte
    decb    %cl         #decrement counter
    jmp scLTEST         #end current loop iteration

    scDONE:
    movl    8(%ebp), %eax       #set return value to pointer to pstring.
    movl    %ebp, %esp      #restore old stack pointer
    popl    %ebp            #restore old FP
    ret             #return to caller function

person Sunspawn    schedule 19.12.2015    source источник


Ответы (2)


cmpb $a, (%eax) вызывает ошибку. Я думаю, вы не хотели сравнивать адрес памяти a со значением (eax). Кстати: сравнение памяти с памятью невозможно в x86. Я думаю, вы хотели сравнить байт в (eax) с непосредственным символом ASCII 'a' (cmpb $97, (%eax)). Вы можете заменить

a:      .byte   97          #a in ascii.

by

.equ a, 97
person rkhb    schedule 19.12.2015
comment
@Sunspawn: вы можете использовать C-подобные выражения в ассемблере: cmpb $'a', (%eax) было бы более компактным символическим способом записи, вместо того, чтобы определять символ с помощью .equ и ссылаться на него. - person Peter Cordes; 20.12.2015
comment
Кроме того, мне потребовалось некоторое время, чтобы выяснить, на что именно жаловался компоновщик: cmpB просил его использовать младший байт адреса как непосредственный, и нет никакого способа попросить компоновщика сгенерировать перемещение только для младшего байта. адреса. - person Peter Cordes; 20.12.2015

вам не обязательно знать таблицу ascii. ты можешь сделать

a: .byte 'a'
person Helder Pereira    schedule 31.10.2016