重定位被截断以适应:R_386_8 针对“.rodata”

Posted

技术标签:

【中文标题】重定位被截断以适应:R_386_8 针对“.rodata”【英文标题】:relocation truncated to fit: R_386_8 against '.rodata' 【发布时间】:2015-12-19 11:56:28 【问题描述】:

尝试在 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

【问题讨论】:

【参考方案1】:

cmpb $a, (%eax) 导致错误。我猜您不想将a 的内存地址与(eax)的值进行比较。顺便说一句:在 x86 中无法进行内存-内存比较。我猜你想将(eax) 的字节与直接的 ASCII 字符 'a' (cmpb $97, (%eax)) 进行比较,你可以替换

a:      .byte   97          #a in ascii.

通过

.equ a, 97

【讨论】:

@Sunspawn:您可以在 asm 中使用类似 C 的表达式:cmpb $'a', (%eax) 将是一种更紧凑的符号方式来编写它,而不是使用 .equ 定义一个符号并引用它。 另外,我花了一段时间才弄清楚链接器到底在抱怨什么:cmpB 要求它使用地址的低字节作为立即数,并且无法询问链接器只为地址的低字节生成重定位。【参考方案2】:

您不必知道 ascii 表。 你可以做

a: .byte 'a'

【讨论】:

以上是关于重定位被截断以适应:R_386_8 针对“.rodata”的主要内容,如果未能解决你的问题,请参考以下文章

内联程序集返回:在创建共享对象时,不能使用针对未定义符号的重定位R_X86_64_32S [重复]

R_X86_64_32S 和 R_X86_64_64 重定位是啥意思?

“重定位 R_X86_64_32S 反对”链接错误

重定位 R_X86_64_32S 对 `.data' 在制作共享对象时不能使用;使用 gcc 重新编译 -fPIC

重定位 R_X86_64_PC32 对符号 _ZTISt13runtime_error@@GLIBCXX_3.4 在制作共享对象时不能使用;使用 -fPIC 重新编译

IBM-3650.M2(7947)服务器没有引导盘怎么重做系统啊?求帮忙!