重定位被截断以适应: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 对 `.data' 在制作共享对象时不能使用;使用 gcc 重新编译 -fPIC
重定位 R_X86_64_PC32 对符号 _ZTISt13runtime_error@@GLIBCXX_3.4 在制作共享对象时不能使用;使用 -fPIC 重新编译